await會阻塞其所在表達式中後續表達式的執行

NO IMAGE

在進入正文之前,我們首先來看一段代碼,這段代碼會輸出什麼呢?

let x = 0;
async function test() {
x += await 2;
console.log(x);	// 輸出什麼?
}
test();
x = 1;

輸出3?還是2?正確答案是:2

如果你知道為什麼會輸出2,那就不用繼續閱讀本文了;但如果你清除這裡面的原因,那麼你可以跟隨我一起分析一下:

  1. 首先我們先記住一句話,那就是異步函數(async方式聲明的函數)不代表其函數內部的所有代碼都是異步方式執行的,這句話什麼意思呢?通俗講就是:在第一個await表達式出現之前,異步函數內部的代碼都是按照同步方式執行的,記住這句話以後我們再繼續往下看

  2. 那麼在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/

相關文章

利用StorageEvent實現頁面間通信

響應式按鈕組件基礎版

淺析Node模塊中module.exports與exports的關係

利用window.requestAnimationFrame實現簡單的數字累加動畫