宏任务与微任务执行顺序为:同步代码→微任务→宏任务;每次宏任务执行后清空全部微任务队列,可用console.log+时间戳、async/await、queueMicrotask及Performance面板验证。

要测试和验证 JavaScript 中宏任务(macrotask)与微任务(microtask)的执行顺序,核心是利用它们在事件循环中的固定调度规则:每次宏任务执行完后,会清空当前所有微任务队列,再取下一个宏任务。
用 console.log + 时间戳 直观观察执行顺序
这是最直接、无需额外工具的方法。关键是在关键节点插入带标识和时间戳的日志,避免仅靠文字顺序误判(因 console 输出可能异步缓冲):
- 使用 Date.now() 或 performance.now() 打点,比单纯写 "1", "2" 更可靠
- 注意:setTimeout(fn, 0) 和 Promise.resolve().then() 分别代表典型的宏/微任务入口
- 示例片段:
// 同步代码
console.log('A', Date.now());
// 微任务
Promise.resolve().then(() => console.log('B', Date.now()));
// 宏任务
setTimeout(() => console.log('C', Date.now()), 0);
// 同步代码继续
console.log('D', Date.now());
// 输出顺序一定是:A → D → B → C(时间戳也严格递增)
用 async/await 拆解嵌套,显式控制微任务边界
async 函数返回 Promise,await 后的代码会被包装进微任务,适合构造多层微任务链并验证“清空式”执行:
- 每个 await Promise.resolve() 都插入一个微任务断点
- 对比 await setTimeout(..., 0)(非法,但可用 new Promise(r => setTimeout(r, 0)) 模拟宏任务)
- 可清晰看到:连续多个 await 不会打断微任务队列,而显式插入的宏任务一定会被延后到下一轮
用 queueMicrotask 替代 Promise.then 做更纯粹的微任务测试
queueMicrotask() 是 ES2020 引入的原生 API,语义比 Promise.then 更轻量、无状态,适合排除 Promise 构造/状态转换干扰:
立即学习“Java免费学习笔记(深入)”;
- 它和 Promise.then 的微任务优先级完全相同,但不涉及 Promise 实例创建开销
- 可用于验证:即使在 Promise.then 回调中调用 queueMicrotask,新微任务仍排在当前轮次末尾(而非立即执行)
- 例如:Promise.resolve().then(() => { console.log(1); queueMicrotask(() => console.log(2)); }); → 输出 1, 2(同轮次)
借助浏览器开发者工具的 Performance 面板 追踪真实调度
当需要确认底层行为(比如是否触发了渲染、是否被其他任务打断),可录制 Performance 跟踪:
- 打开 DevTools → Performance → 点击录制 → 运行你的测试代码 → 停止
- 在火焰图中查找 PromiseResolveThenHandler、TimerFire、FunctionCall 等条目
- 观察它们的时间轴位置和嵌套关系,能直观验证“宏任务执行 → 渲染(如有)→ 微任务执行”这一完整周期


















