Promise.then回调按调用顺序入微任务队列,执行时机取决于Promise状态变化与队列轮转;每个.then返回值决定下一个回调入队时机,独立微任务严格FIFO执行。

多个嵌套的 Promise.then 调用,本质是多个微任务(microtask)按注册顺序排队,但执行时机受 Promise 状态变化和调用栈清空规则共同约束——不是“谁先写谁先跑”,而是“谁先 resolve 且队列轮到谁,谁就执行”。
微任务队列入队时机:只在 then 被调用时入队,不立即执行
每次调用 .then(),只要 Promise 已处于 fulfilled 或 rejected 状态,就会**立刻创建一个微任务并加入当前 microtask 队列尾部**;如果 Promise 还未 settled(即 pending),则回调被缓存,等后续 resolve/reject 触发时再入队。
关键点:
- 入队动作发生在
.then()执行的那一刻,与外层同步代码是否结束无关 - 同一个 Promise 上多次
.then(),回调按调用顺序入队(先进先出) - 嵌套写法(如
p.then(...).then(...))中,第二个.then是在第一个.then的回调返回后才执行的,因此它的微任务一定晚于第一个的微任务入队
嵌套 then 的实际执行顺序:取决于链式返回值与状态传递
看这段典型嵌套链:
Promise.resolve(1)
.then(x => {
console.log('A', x); // A 1
return Promise.resolve(2);
})
.then(x => {
console.log('B', x); // B 2
return 3;
})
.then(x => {
console.log('C', x); // C 3
});
执行逻辑如下:
- 初始 Promise 立即 fulfilled → 第一个
.then回调入微任务队列 - 同步代码结束,开始清空微任务队列 → 执行 A,返回
Promise.resolve(2)→ 触发第二个.then回调入队 - 继续清空队列 → 执行 B,返回普通值 3 → 自动包装为
Promise.resolve(3)→ 第三个.then回调入队 - 继续清空 → 执行 C
注意:每个 .then 的回调本身是同步函数,只是它返回的值决定了下一个 .then 何时能拿到结果、何时入队。
交替执行:不同 Promise 链之间的微任务会交叉排队
如果多个独立 Promise 同时触发,它们的 .then 微任务会按“创建时间”混排进同一个队列:
const p1 = Promise.resolve();
const p2 = Promise.resolve();
p1.then(() => console.log('p1-1'));
p2.then(() => console.log('p2-1'));
p1.then(() => console.log('p1-2'));
输出一定是:
p1-1 → p2-1 → p1-2因为:
- p1.then 先调用 → 微任务1入队
- p2.then 接着调用 → 微任务2入队
- p1.then 再次调用 → 微任务3入队
- 队列顺序就是 1→2→3,严格 FIFO
常见误区澄清
以下说法不准确:
- “嵌套越深,执行越晚” —— 错。深度不影响入队优先级,只影响入队时机(依赖前一个 then 返回)
- “所有 then 回调都在同一轮微任务里执行” —— 错。每个
.then回调都是独立微任务,哪怕写在同一行 - “Promise 构造函数里的 resolve 是同步的,所以 then 也同步” —— 错。resolve 同步改变状态,但
.then回调仍以微任务方式异步执行
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











