1. 程式人生 > >async、await、Promise

async、await、Promise

這三個概念一個一個闡述:

async

async作為一個關鍵字放在一個函式前面,用來表示這個函式是非同步的(執行順序一般是同步、非同步、回撥)非同步函式不會阻塞後面程式碼的執行,先看例子吧

async function timeout() {
  return 'hello world';
}
timeout();
console.log('雖然在後面,但是我先執行');

語法就是在函式之前加async關鍵字,用來表示非同步

我們看瀏覽器控制檯

async 函式 timeout  呼叫了,但是沒有任何輸出,它不是應該返回 'hello world',  先不要著急, 看一看timeout()執行返回了什麼? 把上面的 timeout() 語句改為console.log(timeout())

async 函式返回的是一個promise 物件,如果要獲取到promise 返回值,我們應該用then 方法

我們獲取到了"hello world',  同時timeout 的執行也沒有阻塞後面程式碼的執行。

這時,你可能注意到控制檯中的Promise 有一個resolved,這是async 函式內部的實現原理。如果async 函式中有返回一個值 ,當呼叫該函式時,內部會呼叫Promise.resolve() 方法把它轉化成一個promise 物件作為返回,但如果timeout 函式內部丟擲錯誤呢? 那麼就會呼叫Promise.reject() 返回一個promise 物件

如果函式內部丟擲錯誤, promise 物件有一個catch 方法進行捕獲。

timeout(false).catch(err => {
    console.log(err)
})

await

 await後放一個返回promise 物件的表示式且await 關鍵字只能放到async 函式裡面

現在寫一個函式,讓它返回promise 物件,該函式的作用是2s 之後讓數值乘以2

// 2s 之後返回雙倍的值
function doubleAfter2seconds(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2 * num)
        }, 2000);
    } )
}

現在再寫一個async 函式,從而可以使用await 關鍵字, await 後面放置的就是返回promise物件的一個表示式,所以它後面可以寫上 doubleAfter2seconds 函式的呼叫

async function testResult() {
    let result = await doubleAfter2seconds(30);
    console.log(result);
}

testResult();

開啟控制檯,2s 之後,輸出了60. 

  現在我們看看程式碼的執行過程,呼叫testResult 函式,它裡面遇到了await, await 表示等一下,程式碼就暫停到這裡,不再向下執行了,它等什麼呢?等後面的promise物件執行完畢,然後拿到promise resolve 的值並進行返回,返回值拿到之後,它繼續向下執行。具體到 我們的程式碼, 遇到await 之後,程式碼就暫停執行了, 等待doubleAfter2seconds(30) 執行完畢,doubleAfter2seconds(30) 返回的promise 開始執行,2秒 之後,promise resolve 了, 並返回了值為60, 這時await 才拿到返回值60, 然後賦值給result, 暫停結束,程式碼才開始繼續執行,執行 console.log語句。

  就這一個函式,我們可能看不出async/await 的作用,如果我們要計算3個數的值,然後把得到的值進行輸出呢?

async function testResult() {
    let first = await doubleAfter2seconds(30);
    let second = await doubleAfter2seconds(50);
    let third = await doubleAfter2seconds(30);
    console.log(first + second + third);
}

  6秒後,控制檯輸出220, 我們可以看到,寫非同步程式碼就像寫同步程式碼一樣了,再也沒有回撥地域了。

 

以上內容參考於http://www.cnblogs.com/fanghl/p/9497533.html