定義:Async函數是一個異步操作函數,本質上,Async函數是Generator函數的語法糖。async
函數就是將 Generator 函數的星號(*
)替換成async
,將yield
替換成await
,僅此而已。
定義方式及調用方式:
async function test(){ const a = await fn1(); const b = await fn2(a); } test()
由上可以看出:async函數不需要像 Generator 函數,需要調用next
方法才能執行,其調用方式與普通函數調用方式一致
說明:a)async
表示函數里有異步操作,await
表示緊跟在后面的表達式需要等待結果
b)async函數的返回值是 Promise
返回promise對象:
async function test(a,b){ const x = add(a,b); const y = add(1,x); return y; } function add(x,y){ return x+y; } console.log(test(1,2)) //返回的是promise對象 test(1,2).then(value=>{ console.log(value) //4 promise對象可以使用then()方法取得結果 })
Promise對象狀態的變化:內部所有await
命令后面的 Promise 對象執行完,才會發生狀態改變,除非遇到return
語句或者拋出錯誤。
- return:狀態改變為pending,調用then函數改變為resolve
async function f() { return 'hello world'; } f().then(v => console.log(v)) // "hello world"
- 拋出錯誤:狀態直接改變為reject
async f(){ await add(1,2); throw new Error('出錯了'); } function add(x,y){(resolve,reject)=>{ resolve(x+y) }} f() .then(v=>console.log(v)) .catch(e=>console.log(e)) //出錯了 reject狀態會被catch方法捕捉到
await命令:正常情況下,await
命令后面是一個 Promise 對象。如果不是,會被轉成一個立即resolve
的 Promise 對象
async function f() { return await 123; } f().then(v => console.log(v)) // 123
錯誤處理:如果await
后面的異步操作出錯,那么等同於async
函數返回的 Promise 對象被reject
。防止出錯的方法,就是將其放在try...catch
代碼塊之中。
async function main() { try { const val1 = await firstStep(); const val2 = await secondStep(val1); const val3 = await thirdStep(val1, val2); console.log('Final: ', val3); } catch (err) { console.error(err); } }
使用注意點:
- 最好把
await
命令放在try...catch
代碼塊中 - 多個
await
命令后面的異步操作,如果不存在繼發關系,最好讓它們同時觸發。
// 寫法一 let [foo, bar] = await Promise.all([getFoo(), getBar()]); // 寫法二 let fooPromise = getFoo(); let barPromise = getBar(); let foo = await fooPromise; let bar = await barPromise;
await
命令只能用在async
函數之中,如果用在普通函數,就會報錯。