async妙用

簡介

  • async函數是Generator 函數的語法糖,async函數就是將 Generator 函數的星號(*)替換成async,將yield替換成await,僅此而已。
  • async函數對Generator 函數的改進點有如下幾點:
    • 內置執行器,不須要像Generator 函數要去調用next()才能讓函數執行
    • 更好的語義化
    • 返回的是promise對象

返回promise對象

  • async函數返回一個 Promise 對象。
  • async函數內部return語句返回的值,會成爲then方法回調函數的參數。
  • async函數內部拋出錯誤,會致使返回的 Promise 對象變爲reject狀態。拋出的錯誤對象會被catch方法回調函數接收到
  • 下面見例子:
let testAsync = async function () {
    // throw new Error('拋出一個錯誤~');
    reject()
};
testAsync().then(resolve => {
    console.log(`resolve: ${resolve}`);
}, reject => {
console.log(`reject: ${reject}`);  // 狀態變化成reject的回調函數會執行,若是這裏沒有回調函數,則catch會捕獲,這就是promise的東西了
}).catch(err => {
console.log(`err: ${err}`);
})
  • 任何一個await語句後面的 Promise 對象變爲reject狀態,那麼整個async函數都會中斷執行。
async function f() {
  await Promise.reject('出錯了');
  await Promise.resolve('hello world'); // 不會執行
}
// 第二行的promise語句不會執行
  • 針對這種狀況,有時候咱們但願前面的異步函數執行失敗後,也不要影響後面的代碼執行,這時候就能夠用try-catch和promise的catch處理異常,不至於讓後面的程序不執行

await後面的異步操做出錯,那麼等同於async函數返回的 Promise 對象被reject,因此最好把await命令放在try...catch代碼塊中promise

// 第一種方式
async function f() {
    try {
        await Promise.reject('出錯了');
    } catch (err) {
    }
    return await Promise.resolve('hello world'); 
}
// 第二種當時,用catch來處理前面異步的異常狀況
 async function f() {
     await Promise.reject('出錯了').catch(err => {
        console.log(err); 
     })
     return await Promise.resolve('hello world');
}
  • 若是多個await命令後面的異步操做,若是不存在繼發關係,最好讓它們同時觸發。
let foo = await getFoo();
let bar = await getBar();
// 寫法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);

// 寫法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
// 同時觸發,縮短程序運行時間
  • await命令只能用在async函數之中,若是用在普通函數,就會報錯。
async function dbFuc(db) {
  let docs = [{}, {}, {}];

  // 報錯
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}
相關文章
相關標籤/搜索