同步任務與異步任務
同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;
異步任務:不進入主線程、而進入"任務隊列"(task queue)的任務,只有等主線程任務執行完畢,"任務隊列"開始通知主線程,請求執行任務,該任務纔會進入主線程執行。
事件隊列
- JavaScript是單線程的,所有的同步任務都會在主線程中執行
- 主線程之外,還有一個任務隊列。每當一個異步任務有結果了,就往任務隊列中塞一個時間。
- 當主線程中所有任務都完成了之後,系統會依次讀取隊列中的事件,與之相對應的異步任務進入主線程,開始執行。
- 異步任務之間,會存在差異,所以它們的執行優先級是不同的。大致分爲微任務,如:Promise, MutationObserver,和宏任務, 如setTimeout, setInterval和I/O等。同一事件循環中,微任務永遠在宏任務前執行。
注意: 當new一個Promise是,其resolve中的代碼會立即執行 - 主線程會不斷重複上面的步驟,直到執行完所有任務。
async/await概念
-
async函數,可以理解爲Generator函數的語法糖
async關鍵字: -
被asnyc操作符修飾的函數必然返回一個Promise時,
-
當asnyc函數返回一個值時,Promise的resolve方法負責傳遞
-
當asnyc函數拋出異常時,Promise的reject方法會傳遞這個異常值
-
建立在promise之上,總是和await一起使用的
-
await會返回一個promise對象或一個表達式的值
-
其目的是爲了讓異步操作更優雅,能像同步那樣書寫
Promise的鏈式then()是怎樣執行的?
- Promise多個then鏈式調用,不是連續創建多個微任務並推入微任務隊列的,因爲每一個
then()
的返回值必然是一個Promise,而後續的then()
是上一步then()
返回的Promise的回調 - 傳入Promise構造器的執行器函數內部的同步代碼執行到
resolve()
,將Promise的狀態改變爲<resolve>: undefined
, 然後then中傳入的回調函數console.log('1')
作爲一個微任務被推入微任務隊列中 - 第二個
then()
中傳入的回調函數console.log('2')
此時還沒有被推入微任務隊列,只有上一個then()
中console.log('1')
執行完畢後才繼續執行