微任务在当前宏任务结束后立即全部执行完毕,包括执行过程中新加入的微任务;其队列与宏任务强绑定、不跨轮保留、串行清空,且UI渲染发生在微任务队列清空之后。

微任务会被放到当前宏任务结束后的微任务队列中,紧接着该宏任务执行完毕,JS 引擎会立即清空整个微任务队列——也就是说,所有已入队的微任务(包括中途新推入的)都会在下一个宏任务开始前被依次执行完。
微任务队列是“本轮循环专属”的
它不是全局累积型队列,而是与当前宏任务强绑定:只要一个宏任务执行完,引擎就会检查并执行此时队列里所有已存在的微任务,哪怕它们是在执行过程中陆续加入的(比如 Promise.then 链式调用、或另一个 Promise 的 resolve 触发新 then)。
- 微任务不会跨宏任务保留——上一轮留下的微任务不会拖到下一轮;
- 微任务之间是串行执行的,且不中断:一旦开始执行微任务,就一直执行到队列为空,中间不会插入宏任务;
- 在微任务执行过程中产生的新微任务(例如在 then 回调里再创建 Promise),也会被追加到同一个微任务队列尾部,并在本轮继续执行(即“递归清空”)。
典型例子:链式 Promise 产生嵌套微任务
下面代码中,三个 then 都是微任务,且第二个、第三个是在第一个执行时动态加入的:
console.log('start');Promise.resolve().then(() => {
console.log('1');
Promise.resolve().then(() => console.log('2'));
}).then(() => console.log('3'));
console.log('end');
输出顺序为:start → end → 1 → 2 → 3。其中 '2' 对应的微任务是在执行第一个 then 时才加入队列的,但它仍属于本轮微任务清空阶段,无需等到下一个宏任务。
立即学习“Java免费学习笔记(深入)”;
和宏任务队列的关键区别
宏任务每次只取一个执行,其余排队等待;而微任务队列每次都是全量执行——不管中途新增多少,只要还没开始下一轮宏任务,就全部跑完。
- 宏任务队列:FIFO,逐个取出,每轮仅执行一个;
- 微任务队列:LIFO-like 执行顺序(实际按入队顺序),但一次性清空,无“剩余额度”。
注意:UI 渲染通常在微任务之后、下一个宏任务之前
在浏览器环境中,一次事件循环周期通常是:
同步代码 → 微任务队列清空 → (可选)UI 渲染 → 下一个宏任务。
这意味着,即使你在微任务里反复修改 DOM,用户也只会在所有微任务执行完后看到一次最终效果,而不是逐次渲染。


















