微任务队列在每个宏任务结束后立即一次性清空,优先级高于宏任务;包括Promise.then/catch/finally、queueMicrotask()、MutationObserver等,新微任务加入当前轮末尾并继续执行,而宏任务需等待下一轮。

微任务队列在事件循环中紧随当前同步任务执行完毕后立即清空,且优先级高于宏任务。
微任务的触发时机
每当一个宏任务(如 script 执行、setTimeout 回调、I/O 回调等)运行结束,JS 引擎会立刻检查并**一次性执行完所有当前存在的微任务**,中间不穿插任何其他任务。
- 微任务包括:
Promise.then/catch/finally、queueMicrotask()、MutationObserver回调等 - 注意:微任务是“排队—执行—再排队”,不是“边排边执行”;每次只处理当前已入队的全部微任务,新加入的要等下一轮
- 比如连续调用两次
queueMicrotask(fn),这两个 fn 会在同一轮微任务中依次执行
微任务与宏任务的执行顺序
事件循环每轮按固定节奏推进:执行一个宏任务 → 清空微任务队列 → 渲染(可选)→ 下一个宏任务。
- 即使宏任务里什么都没做,只要它结束,就立刻进入微任务阶段
- 微任务内部再创建新的微任务(如
Promise.resolve().then(() => queueMicrotask(...))),也会被推入当前微任务队列末尾,并在本轮继续执行(直到队列为空) - 但微任务中产生的宏任务(如
setTimeout)要等到下一轮事件循环才执行
实际执行流程示例
以下代码执行顺序能清晰体现微任务的即时性和高优先级:
立即学习“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 是微任务,在第一轮宏任务(script)结束后立即执行;3 是宏任务,排在下一轮。
常见误区提醒
微任务不是“随时插入”,也不是“比宏任务快一点点”,而是有明确的执行窗口和严格清空机制。
- 不要以为
Promise.then总是“立刻”执行——它必须等当前同步代码和正在运行的宏任务彻底结束 - 微任务不会被渲染或用户交互打断,浏览器保证在微任务队列清空前不进行页面重绘
- 过度嵌套微任务(如递归
queueMicrotask)可能导致页面卡顿,因为控制权长时间不交还给事件循环


















