基本用法
執(zhí)行函數(shù)時(shí),遇到await,會(huì)等到異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語(yǔ)句。
如下代碼會(huì)先打印1,再打印2。
function a() {
return new Promise((resolve) => {
setTimeout(function() {
console.log(1);
resolve();
}, 2000)
})
}
async function b() {
await a(); //a要返回一個(gè)Promise對(duì)象,否則await對(duì)它不起作用
console.log(2)
}
b()
返回Promise 對(duì)象
1.async函數(shù)返回一個(gè) Promise對(duì)象。
2.async函數(shù)內(nèi)部return語(yǔ)句返回的值 ,會(huì)成為then方法回調(diào)函數(shù)的參數(shù)。
async function asyncPrint() {
return "hello world";
}
asyncPrint().then(greeting => console.log(greeting)); //hello world
3.async函數(shù)內(nèi)部拋出錯(cuò)誤,會(huì)導(dǎo)致返回的Promise對(duì)象變?yōu)?code>reject狀態(tài)。拋出的錯(cuò)誤對(duì)象會(huì)被catch方法回調(diào)函數(shù)接收到。
async function asyncPrint() {
throw new Error('出錯(cuò)了');
}
asyncPrint()
.then(greeting => console.log(greeting))
.catch(err => console.log(err)); // Error: 出錯(cuò)了
-
async函數(shù)返回的Promise對(duì)象,必須等到內(nèi)部所有await命令后面的Promise對(duì)象執(zhí)行完,才會(huì)發(fā)生狀態(tài)改變,除非遇到return語(yǔ)句或者拋出錯(cuò)誤。也就是說(shuō),只有async函數(shù)內(nèi)部的異步操作執(zhí)行完,才會(huì)執(zhí)行then方法指定的回調(diào)函數(shù)。
await 命令
await后面應(yīng)該返回一個(gè)Promise對(duì)象,如果不是,就直接返回這個(gè)值。
async function f() {
// 等同于
// return 123;
return await 123;
}
f().then(v => console.log(v))
// 123
注意點(diǎn)
- 上面提到因?yàn)閽伋鲥e(cuò)誤會(huì)讓狀態(tài)變?yōu)?code>reject , 所以最好把
await命令放在try...catch代碼塊中, 如下
async function myFun() {
try {
await aa();
} catch (err) {
console.log(err);
}
}
// 另一種寫(xiě)法
async function myFun() {
await aa()
.catch(function (err) {
console.log(err);
});
}
-
getFoo和getBar是兩個(gè)獨(dú)立的異步操作,被寫(xiě)成繼發(fā)關(guān)系。這樣比較耗時(shí),因?yàn)橹挥?code>getFoo完成以后,才會(huì)執(zhí)行getBar,完全可以讓它們同時(shí)觸發(fā)。
let foo = await getFoo();
let bar = await getBar();
多個(gè)await命令后面的異步操作,如果不存在繼發(fā)關(guān)系,最好讓它們同時(shí)觸發(fā)。
// getFoo和getBar都是同時(shí)觸發(fā),這樣就會(huì)縮短程序的執(zhí)行時(shí)間
// 寫(xiě)法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 寫(xiě)法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;