跳到主要内容

Promise 异步总结:状态流转、链式调用、微任务怎么说清?

面试速答(30 秒版 TL;DR)

  • Promise 有三态:pending -> fulfilledpending -> rejected,一旦定型不可再变。
  • new Promise(executor) 里的 executor 同步执行then/catch/finally 的回调是 异步微任务 执行。
  • 链式调用的关键:then 会返回一个新 Promise;回调返回值会决定新 Promise 的状态(返回普通值 -> fulfilled;抛异常 -> rejected;返回 Promise -> 等它)。
  • 常用并发组合:all(全成功)、race(谁先 settle)、any(谁先成功)、allSettled(不短路收集结果)。

状态机心智模型


executor 同步,回调微任务

console.log(1);
new Promise((resolve) => {
console.log(2);
resolve();
}).then(() => console.log(4));
console.log(3);

// 1 2 3 4

解释要点:

  • executor 立即执行打印 2。
  • then 回调排入微任务队列,等当前调用栈清空后执行。

链式调用:返回值决定后续

Promise.resolve(1)
.then((x) => x + 1) // 返回普通值
.then((x) => {
throw new Error("boom"); // 抛错
})
.catch((e) => "recovered") // 返回普通值,链路恢复为 fulfilled
.then(console.log); // "recovered"

finally 的要点(常被问)

  • finally 不改变“值/错误”传递(除非你在 finally 里抛错或返回一个会 reject 的 Promise)。

并发组合(背诵版)

  • Promise.all:全部 fulfilled 才 fulfilled;任一 rejected 立即 rejected。
  • Promise.allSettled:不短路,收集每个结果(fulfilled/rejected)。
  • Promise.race:谁先 settle 用谁的结果。
  • Promise.any:谁先 fulfilled 用谁;全失败才 rejected(聚合错误)。

易错点/坑

  • 以为 resolve 会“立刻执行 then”:不会,then 回调是微任务。
  • 忘记 catch 位置影响错误捕获范围:链式结构要清晰。
  • then 里忘记 return Promise 导致并发顺序错乱。

速记要点(可背诵)

  • 三态不可逆;executor 同步;then/catch 微任务。
  • then 返回新 Promise,返回值/异常决定链路状态。