Async/Await的解析與應用

目錄

  • 什麼是async?
  • async的用法
  • 語法解析
  • 應用案例
  • async 函數的實現原理

一 什麼是async?

  1. 是ES7引入的異步解決方案,使異步操做變得更爲方便
  2. 是Generator函數的語法糖,語法更爲簡潔,語義更明朗簡而言之,async用於申明一個function是異步的;await必須用在異步函數中,等待一個異步方法執行完成。

async和generator對比

上圖左爲Generator的寫法,右爲async的寫法,同爲輸出promise結果小程序

相較於Generator的優勢

  1. 內置執行器: async內置執行器,不一樣於Generator函數須要調用next()才能執行;async和普通函數同樣執行
  2. 更好的語義: 相對於*和yield,async和await語義更明朗; async是異步執行函數,await用於async內,等待後面表達式結果;
  3. 更廣的實用性: await後面能夠跟promise也能夠跟基本數據類型(字符,數值,布爾) 若await後跟基本數據類型,則自動轉成resolved的promise對象
  4. 返回值爲promise Generator 函數的返回值是 Iterator(迭代器),async返回值爲promise,可使用then()進行下一步操做,更爲方便

二 async的用法

async函數返回一個 Promise 對象,可使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到異步操做完成,再接着執行函數體內後面的語句。promise

上面代碼是一個獲取股票報價的函數,函數前面的async關鍵字,代表該函數內部有異步操做。調用該函數時,會當即返回一個Promise對象。異步

p1: 若是存在C請求的調用需在A/B請求以後,但A/B請求是異步執行,如何應用?

顯然使用三個await是不合理的,既然await後能夠跟跟promise,那麼咱們可使用promise.all來知足此需求
複製代碼

同時,async函數還能夠寫成如下幾種形式

3、語法解析

1. 返回 Promise 對象

async函數返回一個promise對象async函數內部return返回的值,會成爲then方法回調函數的參數async

上圖代碼中,函數f內部return命令返回的值,會被then方法回調函數接收到函數

async函數內部拋出錯誤,會致使返回的Promise對象變爲reject狀態。拋出的錯誤對象會被catch方法回調函數接收到優化

2. Promise 對象的狀態變化

async函數返回的 Promise 對象,必須等到內部全部await命令後面的 Promise 對象執行完,纔會發生狀態改變,除非遇到return語句或者拋出錯誤。也就是說,只有async函數內部的異步操做執行完,纔會執行then方法指定的回調函數。spa

上面代碼中,函數getTitle內部有三個操做:抓取網頁、取出文本、匹配頁面標題。只有這三個操做所有完成,纔會執行then方法裏面的console.log。3d

3. await 命令

正常狀況下,await命令後面是一個 Promise 對象,返回該對象的結果。若是不是 Promise 對象,就直接返回對應的值。code

上面代碼中,await命令的參數是數值123,這時等同於return 123。cdn

另外一種狀況是,await命令後面是一個thenable對象(即定義then方法的對象),那麼await會將其等同於 Promise 對象。

上面代碼中,await命令後面是一個Sleep對象的實例。這個實例不是 Promise 對象,可是由於定義了then方法,await會將其視爲Promise處理。

下面這個例子演示瞭如何實現休眠效果。JavaScript 一直沒有休眠的語法,可是藉助await命令就可讓程序停頓指定的時間。下面給出了一個簡化的sleep實現。

await命令後面的 Promise 對象若是變爲reject狀態,則reject的參數會被catch方法的回調函數接收到。

! 注意,上面代碼中,await語句前面沒有return,可是reject方法的參數依然傳入了catch方法的回調函數。這裏若是在await前面加上return,效果是同樣的。可是若是resolve時必需要有return。

! 注意!任何一個await語句後面的 Promise 對象變爲reject狀態,那麼整個async函數都會中斷執行。

4. 異常處理

若是任意一個await後面的異步操做出錯,那麼等同於async函數返回的 Promise 對象被reject。 爲了防止此類狀況發生,可使用try...catch作異常處理

若是有多個await命令,能夠統一放在try...catch結構中;或者根據實際狀況進行分組異常處理。

4、應用案例

1.租賃業務後臺系統屢次消息彈層

場景描述:檢索用戶,若用戶已借繪本大於5本,押金小於100元則依次彈出提醒彈窗(需用戶手動點擊纔可關閉彈窗)

上圖爲代碼實現

2.小馬吉米小程序登陸

場景描述:輸入手機號,獲取驗證碼,校驗手機是否登陸,登陸系統

未優化版本

優化版本

5、async 函數的實現原理

async 函數的實現原理,就是將 Generator 函數和自動執行器,包裝在一個函數裏。

全部的async函數均可以寫成上面的第二種形式,其中的spawn函數就是自動執行器

相關文章
相關標籤/搜索