setImmediate 优先级低于 setTimeout,仅在 Node.js 中有效;其属 check 阶段,setTimeout 属 timer 阶段,阶段顺序为 timer→check;但执行顺序受事件循环阶段影响,官方不保证稳定性,且 setImmediate 已被弃用。

setImmediate 和 setTimeout 的优先级只在 Node.js 中有意义
浏览器环境没有 setImmediate,它仅存在于 Node.js(以及旧版 IE),所以讨论两者谁先谁后,必须明确是在 Node.js 环境下。在浏览器中写 setImmediate 会直接报错。
Node.js 事件循环中,setImmediate 属于 check 阶段,setTimeout 属于 timer 阶段
Node.js 的事件循环比浏览器更细,分为多个阶段,关键两点是:
-
timer 阶段:执行已到期的
setTimeout和setInterval回调 -
check 阶段:执行
setImmediate回调 - 这两个阶段有固定顺序:timer → I/O callbacks → idle/prepare → poll → check → close callbacks
也就是说,即使 setTimeout(fn, 0) 和 setImmediate(fn) 同时注册,在大多数情况下,setImmediate 会在下一个事件循环周期的 check 阶段执行,而 setTimeout(fn, 0) 会在当前或下一个 timer 阶段执行——但实际谁先,还取决于进入事件循环时所处的阶段。
常见场景下的执行顺序规律
以下情况可稳定判断:
立即学习“Java免费学习笔记(深入)”;
- 如果代码在主模块顶层(即初始宏任务)中同时调用
setTimeout(fn, 0)和setImmediate(fn),setImmediate 几乎总在 setTimeout 之后执行(因为 timer 阶段在 check 之前) - 但如果把它们放在
fs.readFile等 I/O 回调里(即 poll 阶段结束后),setImmediate会先于下一轮 timer 执行,此时它反而比同级的setTimeout(fn, 0)更早触发 -
process.nextTick()比两者都高——它不属于任何阶段,而是在当前操作结束后、进入下一阶段前立即执行,优先级最高
不要依赖 setImmediate 和 setTimeout 的竞态顺序
Node.js 官方文档明确指出:不应假设 setImmediate 和 setTimeout 的执行顺序是稳定的。因为:
- 系统性能、定时器精度、事件循环当前所处阶段都会影响结果
- Node.js 11+ 对 timer 阶段做了优化,某些边界下
setTimeout(fn, 0)可能比setImmediate更快 - 从 Node.js 18 开始,
setImmediate已被标记为 deprecated(不推荐使用),官方建议用queueMicrotask或Promise.resolve().then()替代轻量异步,用setTimeout处理真正需要延迟的逻辑


















