setimmediate 在 i/o 回调中总先于 settimeout(0) 执行,因前者在 check 阶段、后者在 timers 阶段;顶层调用顺序不确定;nexttick 和 promise 作为微任务总优先于二者执行。

setImmediate 和 setTimeout(fn, 0) 都不是真正“立即”执行,但它们在事件循环中所处的阶段不同,这直接决定了谁先谁后——关键不在函数名,而在调用时机和所处上下文。
I/O 回调内:setImmediate 总是先于 setTimeout(0)
当两者都在文件读取、网络请求等 I/O 操作的回调里注册时,执行顺序稳定可预测:
- fs.readFile 完成后,回调在 Poll 阶段执行
- 紧接着进入 Check 阶段,触发所有 setImmediate 回调
- setTimeout(0) 的回调仍留在 Timers 阶段,要等下一轮事件循环才处理
所以输出一定是:setImmediate → setTimeout(0)。这不是巧合,而是 Node.js 明确设计的行为。
主模块顶层调用:顺序不确定
如果直接写在脚本最外层(如 index.js 开头),结果可能颠倒:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- setTimeout(0) 实际被强制设为至少 1ms 延迟,受底层计时器精度影响
- Node.js 启动时事件循环尚未完全就绪,Timers 和 Check 阶段谁先轮到取决于初始化节奏
- 系统负载、CPU 占用等细微因素都可能改变首次调度顺序
官方明确提醒:不要依赖这种场景下的执行顺序。
微任务优先级更高:nextTick 和 Promise 不参与阶段竞争
process.nextTick() 和 Promise.then() 属于微任务(microtask),它们不排队进 Timers 或 Check 阶段:
- 每个宏任务阶段(如 Timers、Check)结束后,会立刻清空微任务队列
- 因此它们总比 setImmediate 和 setTimeout(0) 更早执行
- 哪怕写在 setTimeout 回调里,nextTick 也会插队在它之前运行
本质区别:语义定位不同
setImmediate 不是“更快的 setTimeout”,而是为特定场景服务的原生机制:
- setTimeout(0) 表达的是“延迟极短的定时任务”,仍归类为定时器语义
- setImmediate 表达的是“I/O 完成后马上做点什么”,专为填补 Poll 到下一轮 Timers 之间的空档
- 它不抢占当前同步代码,也不饿死其他宏任务,是一种更可控的“异步但非延迟”方案










