process.nextTick 与 setImmediate 的区别及事件循环相位
请说明 Node.js 中 process.nextTick() 和 setImmediate() 的区别,以及在事件循环(Event Loop)各相位中的执行顺序。为什么说 nextTick 不属于事件循环的正式相位?
回答
我是大山
执行顺序:process.nextTick > 微任务(Promise) > setImmediate > 定时器回调
事件循环相位:
- timers:执行
setTimeout/setInterval回调 - pending callbacks:执行延迟到下一轮的 I/O 回调
- idle, prepare:内部使用
- poll:获取新 I/O 事件,执行 I/O 回调
- check:执行
setImmediate回调 - close callbacks:关闭事件回调
nextTick 的特殊性:
process.nextTick不属于事件循环正式相位,而是每个相位切换时插入的微任务队列(称为 nextTickQueue)- 在每个相位完成后、进入下个相位之前,会清空整个 nextTickQueue
- 递归 nextTick 可能饿死 I/O(无限循环阻止事件循环前进)
区别: | 特性 | process.nextTick | setImmediate | |------|-----------------|--------------| | 执行时机 | 当前相位结束立即执行 | check 相位执行 | | 优先级 | 高于 setImmediate | 低于 nextTick | | 递归风险 | 高(阻塞 I/O) | 低(每轮事件循环执行一次) | | 推荐场景 | 延迟执行但需在 I/O 前 | 异步执行,让 I/O 先完成 |
setImmediate(() => console.log('immediate'));
process.nextTick(() => console.log('nextTick'));
// 输出顺序:nextTick → immediate