Event Loop 是什麼?Node.js 明明單執行緒,為什麼還能處理非同步?
Node.js 其實一直在幫我安排「什麼時候該執行什麼」
Event Loop 是什麼?Node.js 明明單執行緒,為什麼還能處理非同步?
Node.js 其實一直在幫我安排「什麼時候該執行什麼」
console.log('A');
setTimeout(() => {
console.log('B');
}, 1000);
console.log('C');
結果不是:
- A
- B
- C
而是:
- A
- C
- B
很多新手第一次看到都會覺得:
- JavaScript 壞掉了嗎?
- 為什麼不是照順序?
- setTimeout 不是寫在前面嗎?
今天進入 Node.js 最核心的概念
Event Loop
我們用實際 console.log 一步一步理解。
JavaScript 真的是單執行緒
Event Loop 是 Node.js 負責安排非同步任務回來執行的機制。
JavaScript 主程式基本上是一次做一件事
例如:
console.log('A');
console.log('B');
console.log('C');
一定是:
- A
- B
- C
因為它是一行一行執行。
如果遇到:
- 讀檔案
- 打 API
- setTimeout
這些需要等待的工作怎麼辦?
如果 JS 傻傻等待
整個網站就會卡死。
所以 Node.js 的做法是
- 先把等待工作交出去
- 之後再回來處理
這就是 Event Loop 的核心。
第一次觀察 Event Loop
建立檔案 event-loop-1.js
console.log('A');
setTimeout(() => {
console.log('B');
}, 1000);
console.log('C');
執行:
node event-loop-1.js
結果:
- A
- C
- B

Event Loop 流程
console.log('A');
直接執行。
所以先印:
- A
setTimeout(...)
Node.js 會
把計時工作交給 Web APIs / Node.js runtime。
不是立刻執行 callback。
console.log('C');
所以印:
- C
1 秒後。
Event Loop 發現,timeout 到了。
於是把 callback:
() => {
console.log('B');
}
放回來執行。
所以最後才印:
- B
Event Loop 白話版流程
你可以先這樣理解:
同步程式
↓
立刻執行
非同步程式
↓
先丟去等待
↓
完成後
↓
Event Loop 再安排回來執行
setTimeout 0 秒也不會立刻執行
setTimeout(..., 0)
很多新手會以為會立刻執行。
但其實不是。
建立 event-loop-2.js
console.log('A');
setTimeout(() => {
console.log('B');
}, 0);
console.log('C');
執行:
node event-loop-2.js
結果:
- A
- C
- B

setTimeout 一定是非同步
就算是 0 毫秒
也會先交出去。
等同步程式跑完,Event Loop 才會把 callback 放回來。
Promise vs setTimeout
建立 event-loop-3.js
console.log('A');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('Promise');
});
console.log('B');
執行:
node event-loop-3.js
結果通常會是:
- A
- B
- Promise
- setTimeout

為什麼 Promise 比 setTimeout 快?
這裡會接觸到 Microtask Queue 和 Macrotask Queue
Promise 的優先級通常比 setTimeout 高。
所以 Promise callback 會先執行
async / await 其實也是 Promise
建立 event-loop-4.js
async function test() {
console.log('A');
await Promise.resolve();
console.log('B');
}
console.log('開始');
test();
console.log('結束');
執行:
node event-loop-4.js
結果:
- 開始
- A
- 結束
- B

為什麼 B 最後?
await Promise.resolve();
會把後面的:
console.log('B');
丟回 Event Loop。
所以同步程式先跑完
之後才回來執行 B
Event Loop 真正重要的是什麼?
JavaScript 不會卡在等待工作。
它會等待的事情先交出去
完成後再回來
- Node.js
- 瀏覽器
- React
- Vue
很多非同步行為的基礎。
感受 Blocking 對 Event Loop 的影響
建立 event-loop-block.js
console.log('開始');
setTimeout(() => {
console.log('Timeout 完成');
}, 0);
while (true) {}
執行:
node event-loop-block.js
你會發現 Timeout 完成 永遠不會出現

為什麼沒有後面?
while(true)
把主執行緒卡死了。
Event Loop 根本沒機會把 callback 放回來執行。
這會讓你真正理解
Event Loop 不是魔法。
主執行緒被 blocking,一切都會卡住。
重點整理
- JavaScript 主程式是單執行緒
- 非同步工作不會立刻執行
- Event Loop 負責安排 callback 回來執行
setTimeout(..., 0)也不是立刻執行- Promise 優先級通常比 setTimeout 高
- async/await 本質上也是 Promise
- blocking 會讓 Event Loop 卡住
메타데이터
- post_id
- de5e2b2ecc59
- slug
- event-loop-是什麼-node-js-明明單執行緒-為什麼還能處理非同步-de5e2b2ecc59
- url
- https://medium.com/@hotdanton08/event-loop-%E6%98%AF%E4%BB%80%E9%BA%BC-node-js-%E6%98%8E%E6%98%8E%E5%96%AE%E5%9F%B7%E8%A1%8C%E7%B7%92-%E7%82%BA%E4%BB%80%E9%BA%BC%E9%82%84%E8%83%BD%E8%99%95%E7%90%86%E9%9D%9E%E5%90%8C%E6%AD%A5-de5e2b2ecc59
- canonical_url
- https://medium.com/@hotdanton08/event-loop-%E6%98%AF%E4%BB%80%E9%BA%BC-node-js-%E6%98%8E%E6%98%8E%E5%96%AE%E5%9F%B7%E8%A1%8C%E7%B7%92-%E7%82%BA%E4%BB%80%E9%BA%BC%E9%82%84%E8%83%BD%E8%99%95%E7%90%86%E9%9D%9E%E5%90%8C%E6%AD%A5-de5e2b2ecc59
- author_url
- https://medium.com/@hotdanton08
- status
- ok
- fetched_at
- 2026-06-09 15:37:30