← Back to list

Event Loop 是什麼?Node.js 明明單執行緒,為什麼還能處理非同步?

Node.js 其實一直在幫我安排「什麼時候該執行什麼」

Chiayu · 2026-05-21 13:11 · 0 claps · 5.4 min read
#javascript #event-loop #settimeout #promises #軟體工程師
Open on Medium ↗
Wiki topics: 🌐 · Web Development

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