Node.js 的事件循环(Event Loop)是怎样的?宏任务与微任务的执行顺序?

Node.js 基于 libuv 实现事件循环,把回调按阶段(phase)依次执行,每个阶段有自己的 FIFO 队列:

┌───────────────────────┐
│        timers         │  setInterval / setTimeout 回调
│     I/O callbacks     │  上一轮 I/O 的延迟回调(如 TCP 错误)
│     idle, prepare     │  内部使用
│       poll            │  取回新的 I/O 事件(文件/网络)
│       check           │  setImmediate 回调
│    close callbacks    │  close 事件(如 socket.destroy)
└───────────────────────┘

微任务在两个节点之间、每个阶段切换前清空(全清空,不是只取一个):

执行顺序口诀:同一圈里,先跑完当前阶段的宏任务队列 → 清空 nextTick 队列 → 清空微任务队列 → 进入下一阶段。

setTimeout(() => console.log('timeout'), 0)
setImmediate(() => console.log('immediate'))
Promise.resolve().then(() => console.log('promise'))
process.nextTick(() => console.log('nextTick'))
// 输出:nextTick → promise → (timeout 与 immediate 顺序不定,取决于事件循环启动耗时)

注意:setTimeout(fn,0) 实际最小约 1ms;在主模块里 setImmediate 通常早于 setTimeout,但在 I/O 回调内部则相反。

同分类其他题目