目錄
核心
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>: