Promise 异步总结:状态流转、链式调用、微任务怎么说清?
面试速答(30 秒版 TL;DR)
- Promise 有三态:
pending -> fulfilled或pending -> 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里忘记returnPromise 导致并发顺序错乱。
速记要点(可背诵)
- 三态不可逆;executor 同步;then/catch 微任务。
- then 返回新 Promise,返回值/异常决定链路状态。