事件循環 (Event Loop) 的介紹
__Notes
JavaScriptEvent LoopAsync ProgrammingWebPerformance
什麼是事件循環 (Event Loop)?
事件循環是 JavaScript 中的一個重要概念,它使得 JavaScript 能夠在單線程環境中處理異步操作。這意味著即使 JavaScript 是單線程的,它仍然可以執行多個任務,而不會阻塞主執行緒。
事件循環的工作原理
事件循環的工作原理可以簡單地描述為以下幾個步驟:
-
執行堆疊 (Call Stack):當一個函數被調用時,它會被推入執行堆疊中,並開始執行。當函數執行完成後,它會從堆疊中彈出。這種結構遵循「後進先出」(LIFO)的原則,即最後被推入堆疊的函數會最先被執行。
-
任務隊列 (Task Queue):當異步操作(如 setTimeout、Promise 等)完成時,相關的回調函數會被推入任務隊列中,等待執行。這種結構遵循「先進先出」(FIFO)的原則,即最早進入隊列的任務會最先被執行。
-
事件循環 (Event Loop):事件循環會不斷檢查執行堆疊是否為空。如果堆疊為空,事件循環會從任務隊列中取出第一個任務並將其推入執行堆疊中執行。
宏任務 (Macro Task) 與微任務 (Micro Task)
在事件循環中,任務可以分為兩種類型:宏任務和微任務。
宏任務 (Macro Task)
宏任務是指那些在事件循環中被處理的主要任務。這些任務包括:
- setTimeout
- setInterval
- I/O 操作
微任務 (Micro Task)
微任務是指那些在當前任務完成後立即執行的任務。這些任務包括:
- Promise 的回調函數
- MutationObserver
微任務的優先級高於宏任務,這意味著在執行下一個宏任務之前,所有的微任務都會被執行。
事件循環的示例
以下是一個簡單的示例,展示了宏任務和微任務的執行順序:
javascript
console.log('Start');
setTimeout(() => {
console.log('Macro Task 1');
}, 0);
Promise.resolve().then(() => {
console.log('Micro Task 1');
});
setTimeout(() => {
console.log('Macro Task 2');
}, 0);
Promise.resolve().then(() => {
console.log('Micro Task 2');
});
console.log('End');
輸出結果
bash
Start
End
Micro Task 1
Micro Task 2
Macro Task 1
Macro Task 2
在這個例子中,首先執行了同步代碼,然後是微任務,最後才是宏任務。
總結
事件循環是 JavaScript 中處理異步操作的核心機制。理解宏任務和微任務的區別對於編寫高效的 JavaScript 代碼至關重要。希望這篇文章能幫助你更好地理解事件循環的運作方式。