微任务比宏任务更优先执行,因为事件循环规定每个宏任务执行完后必须清空全部微任务队列才取下一个宏任务;常见微任务包括Promise回调、queueMicrotask、MutationObserver和async/await后续代码。

微任务比宏任务更优先执行,是因为事件循环的调度规则明确要求:每个宏任务执行完后,必须先清空全部微任务队列,才能取下一个宏任务。
这不是“抢跑”,而是引擎强制的执行节奏。它让 Promise 回调、queueMicrotask 等操作能紧贴当前逻辑完成,避免被渲染或定时器打断。
微任务插在宏任务之间的空隙里
宏任务之间有天然间隔——比如脚本执行完、setTimeout 回调执行完、点击事件处理完之后,都会暂停并检查微任务队列。这个“暂停点”就是微任务的执行窗口。
浏览器不会跳过这个检查,也不会等下一个宏任务排上队才去处理微任务。
- 每轮事件循环只取一个宏任务
- 该宏任务内所有同步代码执行完毕
- 立即执行所有已排队的微任务(包括过程中新加入的)
- 然后才进入 UI 渲染(浏览器环境),再取下一个宏任务
常见微任务有哪些
这些任务一旦注册,就自动进入微任务队列,等待当前宏任务收尾:
- Promise.then/catch/finally 的回调函数
- queueMicrotask() 包裹的函数
- MutationObserver 的回调(监听 DOM 变化)
- async/await 内部本质也是基于 Promise,所以 await 后的代码属于微任务
宏任务是“舞台主角”,微任务是“谢幕前的彩蛋”
你可以把宏任务看作一场演出的完整段落(比如一次点击处理、一段定时器回调),而微任务就像演员谢幕前快速加演的几句台词——它不开启新段落,但一定在本段结束、下一段开始前完成。
立即学习“Java免费学习笔记(深入)”;
例如:
console.log('1');
Promise.resolve().then(() => console.log('2'));
setTimeout(() => console.log('3'), 0);
console.log('4');输出顺序是 1 → 4 → 2 → 3。
因为 '1' 和 '4' 是同步代码(属当前宏任务),'2' 是微任务,在同步结束后立刻执行;'3' 是下一个宏任务,要等微任务清空后才轮到。
微任务机制不是为了“更快”,而是为了可预测的时序控制:确保异步逻辑能紧接同步逻辑执行,不被渲染、I/O 或用户输入延迟干扰。


















