定时器阶段不执行微任务,但结束后立即清空微任务队列;它只执行到期的settimeout/setinterval回调,按创建顺序依次运行,期间产生的微任务(如promise.then)延迟至该阶段结束才执行。

定时器阶段(Timers Phase)本身不执行微任务,但它的结束时刻会触发微任务清空——这是 Node.js 事件循环中一个关键且常被忽略的细节。
定时器阶段只负责执行到期的 setTimeout/setInterval 回调
该阶段的核心职责是检查并执行所有已到期的计时器回调(包括 setTimeout(fn, 0))。它不会主动运行 Promise.then、process.nextTick 等微任务,也不会在回调执行中途插入微任务。
- 所有定时器回调按创建顺序、在到期后统一进入该阶段队列,依次执行
- 即使延迟设为 0,回调也必须等到当前调用栈清空、且轮到 timers 阶段时才执行
- 该阶段内产生的新微任务(比如在 setTimeout 回调里写
Promise.resolve().then(...))不会立刻执行,而是暂存到微任务队列
微任务在定时器阶段结束后立即执行
Node.js 的设计是:每个事件循环阶段结束后,都会同步清空一次微任务队列。所以 timers 阶段一完成,引擎就立刻检查并执行所有待处理的微任务(包括 Promise.then、queueMicrotask),直到队列为空。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 这意味着:一个
setTimeout(() => { Promise.resolve().then(console.log) }, 0)中的then,会在该 setTimeout 回调执行完后、下一个阶段(pending callbacks)开始前执行 -
process.nextTick的优先级更高,它甚至会在微任务队列之前执行(即在当前阶段结束、微任务清空前先跑完 nextTick 队列) - 这种“阶段后清空”机制,是 Node.js 区别于浏览器事件循环的关键点之一(浏览器是宏任务后清空微任务,Node 是每个阶段后都清空)
常见误区澄清
很多人误以为“setTimeout 回调里写的 Promise.then 会和 setTimeout 同步执行”,其实不是——它们属于不同任务类型,执行时机严格分离:
- setTimeout 回调是宏任务,在 timers 阶段执行
- 其内部产生的 Promise.then 是微任务,在 timers 阶段结束后立即执行,而非“嵌套执行”
- 如果 timers 阶段连续执行了多个 setTimeout 回调,所有回调都跑完后,才统一执行一次微任务清空,而不是每执行一个回调就清一次
实际代码验证逻辑
以下代码能清晰体现这一流程:
console.log('1');
setTimeout(() => {
console.log('2');
Promise.resolve().then(() => console.log('3'));
}, 0);
Promise.resolve().then(() => console.log('4'));
console.log('5');
输出顺序为:1 → 5 → 4 → 2 → 3。说明:
– 同步代码(1、5)最先执行;
– 全局 Promise.then(4)作为微任务,在第一轮同步结束、timers 阶段尚未开始前就执行了;
– setTimeout 回调(2)在 timers 阶段执行;
– 它内部的 Promise.then(3)作为新微任务,等到 timers 阶段彻底结束后才执行。










