💡 核心概念(清道夫鐵則):
「執行完一個宏任務(包含主程式)後,Event Loop 的第一優先要務就是去微任務隊列『掃地』。必須把微任務隊列徹底清空,才能去拿取下一個宏任務。」
JavaScript 是單執行緒(Single-threaded)的語言,意味著它只有一個大腦,一次只能做一件事。 為了解決遇到耗時任務(如網路請求、計時器)會「卡死」畫面的問題,瀏覽器提供了一套協調機制,讓 JS 能達到非阻塞(Non-blocking)的異步操作,這套機制就是 Event Loop。
可以將瀏覽器環境想像成一個辦公室:
setTimeout、fetch、DOM 事件。處理完後,會把後續動作(Callback)丟去排隊。在 Event Loop 中,「類別」比「先來後到」更重要。
| 任務類別 | 特性說明 | 常見的 API |
|---|---|---|
| 🚀 微任務 (Microtasks) | 「頭等艙 VIP」 |
優先級極高。只要隊伍裡有任務,就必須一次性全部清空,哪怕執行中又產生新的微任務。 | Promise.then / .catch / .finally
queueMicrotask
process.nextTick (Node.js)
MutationObserver |
| 🚌 宏任務 (Macrotasks) | 「經濟艙」
優先級較低。每次 Event Loop 循環只會抓出最早進入等待的一個來執行。 | 整體 <script> 主程式
setTimeout / setInterval
DOM 事件 (click, input 等)
網路請求 (Ajax / fetch) |
一個完整的事件循環步驟,本質上是一個無窮無盡的「宏 ➔ 全部微 ➔ 宏 ➔ 全部微...」循環:
<script> 推入 Call Stack 執行直到結束。在底層引擎眼中,並沒有神聖不可侵犯的「主任務」,它就只是 Event Loop 誕生後接手的第一號宏任務。