async await詳解
async await
本身就是promise + generator
的語法糖。
本文主要講述以下內容
- async awiat 實質
- async await 主要特性
async await 實質
下面使用 promise + generate 實現 async await
// 轉換目標 async1 // async function async1() { //console.log('async1 start'); //await async2(); //console.log('async1 end'); // } function async1() { // 將 async 轉換成 *,將 awiat 轉換成 yield var awaitInstance = (function* () { console.log('async1 start'); yield async2(); console.log('async1 end'); })() // 自動執行 await 及後續程式碼 // 簡單起見,不處理異常情況 function step() { var next = awaitInstance.next(); // 使用Promise獲取 非同步/同步 方法的結果,再執行下一步 Promise.resolve(next.value).then(function (val) { if (!next.done) step(); }) } step(); // 返回Promise return Promise.resolve(undefined); }
async await 特性
- async 一定會返回 promise
// 案例1: 不設定return async function fn() {} fn().then(alert); // alert -> undefined // 案例2:return非promise async function f() { return 1 } f().then(alert); // alert -> 1 // 案例3: return Promise async function fn() { return Promise.resolve(2); } fn().then(alert); // alert -> 2
- async 中程式碼是直接執行的(同步任務)
console.log(1); async function fn() { console.log(2); await console.log(3) console.log(4) } fn(); console.log(5); // 列印 1 2 3 5 4 // 為何後面是 3 5 4 ? 往下看
- await是直接執行的,而await後面的程式碼是 microtask。
async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } // 類似於 async function async1() { console.log('async1 start'); Promise.resolve(async2()).then(() => { console.log('async1 end'); }) }
- await後面程式碼會等await內部程式碼全部完成後再執行
async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { return new Promise(function(resolve) { setTimeout(function() { console.log('sleep 2s'); resolve('do'); }, 2000) }) } async1(); // 列印結果 // async1 start -> sleep 2s -> async1 end
- await操作符用於等待一個Promise 物件。它只能在非同步函式 async function 中使用。參考MDN
附: 在chrome版本 73.0.3683.86(64 位)中, await是可以直接使用的。 var x = await console.log(1)
End
持續更新中來Github 點顆:star:吧