在進入正文之前,我們首先來看一段程式碼,這段程式碼會輸出什麼呢?
let x = 0;
async function test() {
x += await 2;
console.log(x); // 輸出什麼?
}
test();
x = 1;
複製程式碼
輸出3?還是2?正確答案是:2
如果你知道為什麼會輸出2,那就不用繼續閱讀本文了;但如果你清除這裡面的原因,那麼你可以跟隨我一起分析一下:
-
首先我們先記住一句話,那就是非同步函式(async方式宣告的函式)不代表其函式內部的所有程式碼都是非同步方式執行的,這句話什麼意思呢?通俗講就是:在第一個await表示式出現之前,非同步函式內部的程式碼都是按照同步方式執行的,記住這句話以後我們再繼續往下看
-
那麼在test函式內部,哪些程式碼是按同步方式執行的呢?首先我們可以將
x += await 2
這行程式碼稍微變換一下形式,變換為:x = x + await 2
,表示式右邊的x是取值操作,並且按同步方式執行的,所以在執行到await時,右邊的x已經取值完成,並且被取到的值0
替換,然後才輪到test函式外的x = 1
這行程式碼執行,x += await 2
相當於x = 0 + await 2
,所以最終輸出:2
現在,我們稍微對上面的程式碼做一下修改:
let x = 0;
async function test() {
x = (await 2) + x;// 把await放在x前面
console.log(x); // 這裡又輸出什麼?
}
test();
x = 1;
複製程式碼
如果你已經明白了前面我所說的,那麼我想你應該可以給出正確的答案,那就是輸出:3。原因是:await 2
這次被放在了x
表示式的前面,所以x
的取值操作是非同步執行的,也就是說x = 1
會先被執行,然後才是test函式中x
的取值操作,由於test函式中的x形成了閉包,所以x = (await 2) + x
相當於x = (await 2) + 1
,所以最終輸出:3
結論
上面程式碼的關鍵是:test函式中x
的取值操作與x = 1
這行程式碼執行順序先後的問題,所以我們可以得出一個結論:await會阻塞其所在表示式中後續表示式的執行
原文連結:https://www.guoyunfeng.com/2018/05/28/await/