事件循环执行顺序为同步代码→微任务(promise.then、queuemicrotask)→宏任务(settimeout);1→5→3→4→2是确定输出,因宏任务后清空全部微任务队列,settimeout即使设0也须等当前宏任务及所有微任务完成。

可以通过嵌套 setTimeout、Promise.then、queueMicrotask 和同步代码,配合 console.timeLog 或带序号的 console.log,清晰观察事件循环各阶段的执行顺序。
核心验证逻辑:用时间戳+标记区分宏任务与微任务
JavaScript 事件循环中,每次宏任务执行完后,会清空当前所有微任务队列;下一轮宏任务(如 setTimeout)要等本轮全部微任务执行完毕才开始。验证的关键是构造可预测的执行序列:
- 同步代码 → 立即执行(宏任务起点)
-
Promise.resolve().then()/queueMicrotask()→ 当前宏任务末尾触发(微任务) -
setTimeout(() => {}, 0)→ 下一轮宏任务(即使设为 0,也至少等完当前宏任务 + 所有微任务)
一段可直接运行的验证代码
把以下代码粘贴到浏览器控制台或 Node.js(v11+)中运行:
使用固定的 Next.js/Tailwind/Prisma 技术栈构建并记录独立 SaaS 项目,仅将 FastAPI 用于 Python 工作负载,并遵循严格的架构规范。
console.log('1. 同步开始');
setTimeout(() => {
console.log('2. setTimeout 宏任务(第一轮)');
}, 0);
Promise.resolve().then(() => {
console.log('3. Promise.then 微任务(第一轮)');
});
queueMicrotask(() => {
console.log('4. queueMicrotask 微任务(第一轮)');
});
console.log('5. 同步结束');
// 输出顺序一定是:1 → 5 → 3 → 4 → 2
进阶验证:多层嵌套与 nextTick 行为对比
在 Node.js 中还可加入 process.nextTick(优先级高于 Promise.then),进一步验证微任务内部优先级:
-
process.nextTick在当前操作完成后立即执行,早于所有 Promise 微任务 - 多个
nextTick会按注册顺序排队,但都在本轮宏任务结束前执行完 - 浏览器无
nextTick,可用queueMicrotask模拟其“最高微任务优先级”语义
注意事项与常见误区
验证时需注意环境差异和细节干扰:
- 不要依赖
setTimeout(..., 0)的“零延迟”,它实际最小约 4ms(浏览器)或 1ms(Node.js),但顺序不受影响 - 避免在微任务中抛出未捕获错误,否则可能中断后续微任务执行(如 Promise.reject() 未 catch)
- Chrome DevTools 的 console 输出有时因异步渲染出现视觉错序,建议用
console.timeLog或写入数组再统一打印 - async/await 本质是 Promise 语法糖,
await Promise.resolve()后的代码属于新的微任务,不是同步










