Promise.then 比 setImmediate 先执行,因其属微任务,在当前宏任务末尾立即清空执行;setImmediate 属宏任务,需等待微任务清空及 poll 阶段后才在 check 阶段运行。

setImmediate 和 Promise.then 在 Node.js 中执行顺序不同,根本原因在于它们分属不同任务队列:前者是宏任务(check 阶段),后者是微任务(Promise Job Queue)。
Promise.then 属于微任务,紧接当前同步代码之后执行
Promise.then 的回调被推入微任务队列,在当前宏任务(比如整个 script 执行)结束后、进入下一事件循环阶段前,立刻清空该队列。它不等待 I/O 或定时器,也不受 setImmediate 所在阶段影响。
- 即使 Promise 立即 resolve,.then 回调也绝不会在当前同步语句中间插入,而是在本轮宏任务末尾统一执行
- 多个 .then 链式调用会按注册顺序依次进入微任务队列,连续执行,中间不穿插其他类型任务
- 它比 setTimeout(fn, 0) 和 setImmediate 都早,但晚于 process.nextTick
setImmediate 属于宏任务,在 check 阶段运行
setImmediate 回调被放入事件循环的 check 阶段队列,该阶段位于 poll 阶段之后、下一个 timers 阶段之前。这意味着它必须等当前轮次中所有 I/O 回调处理完,且微任务已清空后,才获得执行机会。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 即便写在 Promise.then 后面,setImmediate 也要等到下一轮事件循环的 check 阶段,所以总比 .then 晚
- 如果 poll 阶段因无 I/O 而空转,Node 可能直接跳到 check,此时 setImmediate 会较快触发;但只要有微任务积压,它就得排队等
- 它和 setTimeout(fn, 0) 不在同一阶段:后者在 timers 阶段,理论上可能比 setImmediate 更早或更晚,取决于系统计时精度和上一轮是否遗留 timer
实际执行顺序可概括为:同步代码 → process.nextTick → Promise.then → setImmediate → setTimeout
这个顺序不是凭空约定,而是由事件循环各阶段的执行规则决定的。例如:
console.log('start');
Promise.resolve().then(() => console.log('then'));
setImmediate(() => console.log('setImmediate'));
console.log('end');
输出一定是:start → end → then → setImmediate。因为 .then 是微任务,setImmediate 是后续宏任务阶段的任务。
注意 setImmediate 的“立即”是误导性命名
它并不表示“马上执行”,而是“在本轮事件循环的 check 阶段执行”。如果当前 tick 已有大量微任务或 I/O 回调未处理完,它的实际延迟可能远超预期。相比之下,Promise.then 的时机更确定、更靠前,适合需要尽快响应但又不能阻塞主线程的逻辑。

















