宏任务执行完毕后,JavaScript引擎会自动清空微任务队列,依次同步执行所有微任务直至队列为空,再继续下一个宏任务;微任务包括Promise.then/catch/finally、MutationObserver回调等,遵循FIFO但必须本轮全部执行完。

宏任务执行完毕后,JavaScript 引擎会自动检查并执行当前微任务队列中的所有任务,这个过程不需要手动触发,是事件循环(Event Loop)的固有机制。
微任务在宏任务结束后自动清空
每当一个宏任务(如 script 初始化、setTimeout 回调、setInterval 回调、I/O 回调等)执行完,控制权交还给事件循环时,引擎会立即:
- 检查微任务队列(Microtask Queue)是否为空
- 如果不为空,**依次、同步、全部执行完**所有微任务(如 Promise.then/catch/finally、MutationObserver 回调)
- 直到微任务队列变空,才继续选取下一个宏任务
注意:不是“执行一个”,而是“清空全部”
微任务队列采用 FIFO(先进先出),但关键在于:一次宏任务结束后,引擎会持续从队列头部取出微任务执行,且新加入的微任务也会被本轮清空。例如:
Promise.resolve().then(() => {
console.log(1);
Promise.resolve().then(() => console.log(2));
});
// 输出:1 → 2(都在同一轮微任务清空中)
常见误区:setTimeout 不会“触发”微任务
setTimeout 是宏任务,它本身不会触发微任务清空;它只是把自己加入宏任务队列。真正触发微任务清空的是它自己执行完毕的那一刻。换句话说:
立即学习“Java免费学习笔记(深入)”;
- 你无法用代码“主动触发”微任务清空(比如没有类似
flushMicrotasks()的 API) - 你也不能打断或暂停微任务执行——一旦开始,必须全部执行完
- 想“等待微任务完成”,可用
await Promise.resolve()(它会把后续逻辑推到下一轮微任务末尾)
调试技巧:观察执行时机
可通过混合宏/微任务来验证执行顺序:
console.log('start');
setTimeout(() => console.log('timer'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('end');
// 输出:start → end → promise → timer
这说明:同步代码(宏任务)执行完 → 立即清空微任务 → 再取下一个宏任务(setTimeout)


















