async函數(shù)也是用來(lái)解決異步編程的書(shū)寫(xiě)問(wèn)題,比promise更簡(jiǎn)潔,它把異步代碼的書(shū)寫(xiě)方式簡(jiǎn)化的幾乎和同步代碼書(shū)寫(xiě)方式一樣。
async異步函數(shù)內(nèi)部有一個(gè)await關(guān)鍵字(也可以稱為await指令)。async函數(shù)的返回值是一個(gè)promise實(shí)例,在async函數(shù)執(zhí)行時(shí)首次遇到return或者await關(guān)鍵字后返回。
await關(guān)鍵字后面跟的是一個(gè)變量(也可說(shuō)是一個(gè)值,這里假設(shè)為a),如果該變量的值是一個(gè)promise對(duì)象,則中斷執(zhí)行保持等待,當(dāng)該promise對(duì)象resolve后,繼續(xù)向下執(zhí)行。如果該變量的值不是promise實(shí)例,則使用Promise.resolve(a)的形式包裝該變量。
很多時(shí)候我們看到await后面跟的是一個(gè)語(yǔ)句,等于接受語(yǔ)句的返回值,即先執(zhí)行語(yǔ)句,然后await關(guān)鍵字等待的是語(yǔ)句的返回值,如果語(yǔ)句沒(méi)有返回值則為undefined
await關(guān)鍵字會(huì)返回值,我們可以使用一個(gè)變量來(lái)接收。返回值就是其后跟的promise實(shí)例resolve的參數(shù)。
如果await關(guān)鍵字后的promise實(shí)例的reject執(zhí)行了(假設(shè)有參數(shù)arg),那么async函數(shù)中斷執(zhí)行,同時(shí)async函數(shù)返回的promise實(shí)例的reject執(zhí)行,并接收參數(shù)arg。需要注意,如果await后的promise實(shí)例reject了,而async函數(shù)返回的promise實(shí)例沒(méi)有注冊(cè)失敗回調(diào),瀏覽器會(huì)報(bào)錯(cuò)(實(shí)測(cè)chrome瀏覽器會(huì)報(bào)錯(cuò))
async函數(shù)在執(zhí)行中遇到return語(yǔ)句時(shí)會(huì)退出函數(shù)的執(zhí)行。如果函數(shù)執(zhí)行到最后的代碼都沒(méi)有遇到return語(yǔ)句,則系統(tǒng)會(huì)在最后自動(dòng)加上return undefined。這時(shí)async函數(shù)返回的promise實(shí)例的resolve或者reject就會(huì)執(zhí)行。如果return一個(gè)非promise實(shí)例,則執(zhí)行resolve,并接收return出的值為參數(shù)。如果return一個(gè)promise實(shí)例,則變成了狀態(tài)關(guān)聯(lián)。
//定義異步函數(shù)h
async function h() {
//創(chuàng)建一個(gè)promise實(shí)例
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ssss')
}, 5000)
})
//等待promise完成
let b = await promise; //定義變量b接收await的返回值,
setTimeout(() => {
console.dir(b + 1000); //打印ssss1000
}, 5000)
}
//調(diào)用函數(shù)h
//返回值是一個(gè)promise實(shí)例
let a = h();