天天看點

細說 async/await

目錄

核心

1. 執行 async 函數,預設傳回一個 promise 對象

2. await 相當于 promise 的 then

3. try...catch 可捕獲異常,代替了 promise 的 catch

細說

1. async

2. await

3. await 等到之後,做了一件什麼事情?

4. 使用 async/await 改寫 then 鍊

其他相關傳送門

Promise異步操作詳解

Promise詳細用法

手寫一個Promise

<code>async</code> 是ES7新出的特性,表明目前函數是異步函數,不會阻塞線程導緻後續代碼停止運作。

<code>async</code> 函數,就是 Generator 函數 的文法糖。

相較于 Generator,<code>async</code> 函數的改進在于下面四點:

内置執行器:<code>Generator</code> 函數的執行必須依靠執行器,而 <code>async</code> 函數自帶執行器,調用方式跟普通函數的調用一樣

更好的語義:<code>async</code> 和 <code>await</code> 相較于 <code>*</code> 和 <code>yield</code> 更加語義化

更廣的适用性:<code>co</code> 子產品約定,<code>yield</code> 指令後面隻能是 <code>Thunk</code> 函數或 <code>Promise</code>對象。而 <code>async</code> 函數的 <code>await</code> 指令後面則可以是 <code>Promise</code> 或者 原始類型的值(<code>Number</code>,<code>string</code>,<code>boolean</code>,但這時等同于同步操作)

傳回值是 Promise:<code>async</code> 函數傳回值是 <code>Promise</code> 對象,比 <code>Generator</code> 函數傳回的 <code>Iterator</code> 對象友善,可以直接使用 <code>then()</code> 方法進行調用

上面的執行結果是先列印出<code>'我先執行'</code>,雖然是上面<code>asyncFn()</code>先執行,但是已經被定義異步函數了,不會影響後續函數的執行。

async 定義的函數内部會預設傳回一個 promise 對象:

如果函數内部發現不是異常或者<code>reject</code>,則判定成功,這裡可以<code>return</code>各種資料類型的值,<code>false</code>,<code>NaN</code>,<code>undefined</code>...總之,都是<code>resolve</code>

如果函數内部抛出異常或者是傳回<code>reject</code>,都會使函數的<code>promise</code>狀态為失敗<code>reject</code>

在<code>async</code>裡,必須要将結果<code>return</code>出去,不然的話不管是執行<code>reject</code>還是<code>resolved</code>的值都為<code>undefine</code>

<code>await</code> 意思是 <code>async wait</code>(異步等待)。

<code>await</code> 後面接一個會 <code>return new promise</code> 的函數并執行它

<code>await</code> 隻能放在 <code>async</code> 函數裡

任何 <code>async</code> 函數都會預設傳回 <code>promise</code>,并且這個 <code>promise</code> 解析的值都将會是這個函數的傳回值,而 <code>async</code> 函數必須等到内部所有的 <code>await</code> 指令的 <code>Promise</code> 對象執行完,才會發生狀态改變。

就是說,必須等所有<code>await</code> 函數執行完畢後,才會告訴<code>promise</code>我成功了還是失敗了,執行<code>then</code>或者<code>catch</code>

把<code>await</code>和成功後的操作放到<code>try</code>裡,失敗的放在<code>catch</code>:

await 後面是 rejected 狀态的栗子:

用 <code>try...catch</code> 捕獲異常即可:

await 下面所有的代碼都是異步

<code>await</code>等到的結果分2種:

不是promise對象

如果不是 promise , await會阻塞後面的代碼,先執行async外面的同步代碼,同步代碼執行完,再回到async内部,把這個非promise的對象,作為 await表達式的結果。

是promise對象

如果是 promise 對象,await 也會阻塞async後面的代碼,先執行async外面的同步代碼,等着 Promise 對象 fulfilled,然後把 resolve 的參數作為 await 表達式的運算結果。

如果asycn裡的代碼都是同步的,那麼這個函數被調用就會同步執行

相比于 <code>Promise</code> ,<code>async/await</code> 能更好地處理 <code>then鍊</code>

使用<code>then的鍊式調用</code>:

使用 <code>async/await</code>:

下一篇: samba

繼續閱讀