Promise回调属于微任务,因其状态变更时被规范定义为PromiseReactionJob并加入微任务队列,优先于宏任务执行;已决议Promise的then回调立即入队,未决议则待状态变更后入队;async/await本质基于Promise.then,故await后代码也进入微任务队列。

Promise 的回调(then、catch、finally 中传入的函数)在 Promise 状态变为 fulfilled 或 rejected 后,并不会立即执行,而是被放入微任务队列(microtask queue),等待当前同步代码执行完、且调用栈清空后,由事件循环(event loop)在下一次“检查微任务”阶段统一执行。
Promise 回调为什么属于微任务
这是 JavaScript 规范(ECMAScript 和 HTML Living Standard)明确规定的:当 Promise 状态改变时,其关联的 then/catch 回调会被包装为一个 Job(具体是 PromiseReactionJob),并加入微任务队列。这保证了 Promise 链的执行具有高优先级和可预测的顺序,优于 setTimeout、setInterval 等宏任务。
什么时候触发入队?不是创建时,而是状态变更时
关键点在于:Promise 构造函数内部的执行器(executor)是同步运行的,但它的回调不会立刻执行;只有当 Promise 变为 fulfilled/rejected,且已有 then 等方法注册监听时,对应的回调才被排入微任务队列。
- 如果 Promise 已 settled(已决议),但之后才调用
then,该回调会立即入微任务队列(规范要求“尽快”执行,即下一个微任务轮次) - 如果 Promise 还未 settled,
then注册的是“等待态监听”,等将来状态变更时再入队 -
Promise.resolve().then(...)这类已决议的 Promise,then回调会在当前任务结束后、下一个微任务中执行
和 async/await 的关系:本质相同
async 函数返回的 Promise,其内部 await 后的代码,底层也是通过 Promise.then 实现的。所以 await 后面的语句,等价于写在 then 回调里,同样进入微任务队列。
立即学习“Java免费学习笔记(深入)”;
例如:
async function foo() {console.log('1');
await Promise.resolve();
console.log('2'); // 这行实际在微任务中执行
}
foo();
console.log('3');
输出顺序是 1 → 3 → 2,因为 console.log('2') 被安排在微任务中,晚于同步的 console.log('3')。
如何验证它进了微任务队列
可以通过与 setTimeout(宏任务)对比观察执行时机:
setTimeout(() => console.log('macrotask'), 0);
console.log('sync');
输出一定是:sync → microtask → macrotask。这是因为事件循环每次执行完一个宏任务后,会清空整个微任务队列,再取下一个宏任务。


















