微任务队列总在当前宏任务结束后、下一次渲染前同步连续清空,执行所有已排队及动态追加的微任务,期间不插入宏任务、不中断渲染,是浏览器保障ui一致性的强制时序。

微任务队列在每次事件循环的宏任务执行完毕后立即清空,且在渲染前完成——这是浏览器保障响应性和一致性的关键机制,不是可协商的调度权争夺,而是严格定义的执行时序。
微任务队列何时被清空?
它总是在当前宏任务(如点击回调、setTimeout 回调、script 标签执行)结束后、下一次渲染帧开始前,**同步、连续、一次性**地执行完所有已排队的微任务(Promise.then/catch/finally、queueMicrotask、MutationObserver 回调等)。中间不会插入宏任务,也不会中断渲染。
渲染进程有没有“调度权”?
没有独立的“调度权”概念。渲染是事件循环的一个阶段,由浏览器自主触发,但有明确前提:当前宏任务 + 所有微任务必须全部执行完毕。也就是说,渲染的时机是被微任务清空动作“让出”的,而非“争夺”来的。若微任务持续入队(比如在 Promise 回调里不断 new Promise),就会阻塞渲染,造成界面卡顿——这不是权争失败,而是违反了及时退出微任务循环的约定。
开发者能做什么?
理解并尊重这个顺序,避免无意中制造“微任务洪水”:
- 不在 Promise 回调中无条件递归调用 queueMicrotask 或返回新 Promise 链
- 对大量 DOM 变更,优先使用 requestIdleCallback 或分片处理(如每轮微任务只处理 10 个节点),把压力分散到多个事件循环周期
- MutationObserver 的回调属于微任务,批量 DOM 修改会合并为一次回调,但回调内部仍需避免同步耗时操作
不复杂但容易忽略:微任务不是更快的 setTimeout,它是渲染前的最后守门人。守好这道门,界面才不会失守。











