這是一段幫助你更了解 Promise 與 CallStack/Microtask Queue 的程式碼,希望你在得到答案的同時,也更加了解 Promise 是如何運作的。
在看程式碼之前,我們要先知道 JavaScript 有幾個重要的運作原理:
- Event Loop: 遵循以下步驟不停的執行 JavaScript 的機制
- Evaluate Script: 逐行執行程式碼,將函式放入 CallStack ,直到 CallStack 為空
- Run a Task: 從 Task Queue 取出一個最舊的 Task 放入 CallStack 執行
- Run Microtasks: 從 Microtask Queue 取出所有 Microtask 至 CallStack 執行
- Rerender the UI: 更新 UI
- 重複以上步驟
- CallStack: LIFO 的 stack 資料結構,追蹤目前執行到的函式,每層代表一個函式
- Task Queue: FIFO 的 queue 資料結構,存放待執行的 Tasks
例如:setTimeout、setInterval - Microtask Queue: FIFO 的 queue 資料結構,存放待執行的 Microtasks
例如:Promise、MutationObserver
new Promise(resolve => {
resolve(1);
Promise.resolve().then(() => console.log(2));
console.log(3);
}).then(t => console.log(t));
console.log(4);
接下來,我們來看看這段程式碼的執行順序:
A. Evaluate Script
- 將
new Promise
的 Callback 函式放到 CallStack - 執行
resolve(1)
- 執行
Promise.resolve()
,將() => console.log(2)
函式放到 Microtask Queue - 將
t => console.log(t)
函式放到 Microtask Queue - 執行
console.log(3)
👉 3 - 清空 CallStack
- 執行
console.log(4)
👉 4
B. Run Microtasks
如果對於以上的解釋感到困惑,可以參考下方的 JavaScript visualizer 視覺化了解程式碼的執行