async/await

限定程式依序(同步)執行

async/await

  • ES7中提供的異步解決方案(要搭配promise)(可增加promise的可讀性),在迴圈中使用更加靈活簡潔。

  • async

    • async本質上是對 promise 的封裝

    • async一定會回傳 promise 物件(若是字串,會自動轉為promise物件)

    • 對async來說await不是必須的,但await一定要在async內

    • 如果有很多層呼叫 async 方法,上層的方法也要用 async 呼叫,不能直接用一般函式呼叫

  • await

    • await 會等待這段函式完成後在往下繼續執行,這是一個卡住的概念

    • await 後方一定要接 promise,但不必寫 .then(..) ,直接可以得到返回值。

    • 當await中的某個 Promise 變成 reject 時,函數暫停執行,後面的程式不會執行。

// === 範例一 ===
// 定義暫停功能,要當成 await 所以要返回 promise
var sleep = function (time) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve();
        }, time);
    })
};

var start = async function () {
    console.log('start');
    
    await sleep(3000);
    
    console.log('end');
};

start();
//控制台先输出start,稍等3秒后,输出了end。


// === 範例二 ===
// 1秒後返回雙倍的值
function doubleAfterSecond(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve( num*2 )
        }, 1000);
    } )
}

async function testResult() {
    // 不用 then 接值,可直接依序得到返回值 
    let first = await doubleAfterSecond(30);
    let second = await doubleAfterSecond(50);
    let third = await doubleAfterSecond(30);
    
    // 上方非依賴關係,可用 promise.all 修改為同步執行
    /*
    let[first, second, third] = await Promise.all(
        await doubleAfterSecond(30),
        await doubleAfterSecond(50),
        await doubleAfterSecond(30)
    )
    */
    
    
    console.log(first + second + third);
}

// console 輸出 220


// === 範例三 ===
// 用async封裝promise
async function es7(){
  //await後方接promise
  //下方會逐一次序執行
  //為了避免單一錯誤會中斷後續的執行
  // 最好用try/catch將所有的await包起來
  try {
    let a = await Promise.resolve(1)
    let b = await Promise.resolve(a+2)
    let c = await Promise.resolve(3+b)
      
    return c
  } catch (err) {
    console.log(err); // 这里捕捉到错误 `error`
        
  }
}

//promise物件,可用then來獲得最後值
es7().then(function(data)
  console.log(data)
)
// console 輸出 6

Last updated