请比较 Promise.all 与 Promise.allSettled 的行为差异,并说明各自适用的典型场景。
考察说明
考查对 ES6 及之后 Promise 静态方法语义差异的理解,以及根据错误处理需求选择合适方法的能力。
回答思路
- 【回答框架 1】Promise.all 接收一个可迭代的 Promise 集合,返回一个新的 Promise。当所有 Promise 都成功时,返回一个包含每个结果(按原顺序)的数组;只要有一个 Promise 被拒绝,整个 Promise 立即进入 rejected 状态,并携带第一个拒绝的原因,后续的 Promise 结果会被忽略。
- 【回答框架 2】Promise.allSettled 同样接收一个 Promise 集合,但无论每个 Promise 是 fulfilled 还是 rejected,它都会等待所有 Promise 完成,并返回一个对象数组,每个对象包含 status 属性(值为 'fulfilled' 或 'rejected'),以及对应的 value 或 reason。它不会因为某个 Promise 失败而短路。
- 【回答框架 3】选择依据:如果所有请求必须全部成功才能继续,且任一失败即终止后续逻辑,应使用 Promise.all;如果需要等待所有请求完成,而不关心个别失败,并希望收集每个请求的结果(例如批量上报、并行拉取数据并独立处理错误),则应使用 Promise.allSettled。
- 【回答框架 4】额外注意:Promise.all 的短路行为有助于快速失败,但可能丢失部分成功结果;Promise.allSettled 会等待所有,但可能增加等待时间。两者都返回数组,顺序与传入的迭代对象顺序一致。
- 【关键点 1】Promise.all 是快速失败,所有成功才成功,任一拒绝即拒绝。
- 【关键点 2】Promise.allSettled 等待所有完成,不短路,返回每个 Promise 的结果对象。
- 【关键点 3】根据是否依赖所有成功来决定选择,追求完整结果用 allSettled。
- 【易错点 1】误以为 Promise.all 会等待所有 Promise 完成后才拒绝,实际是只要有一个失败立即拒绝。
- 【易错点 2】忽视 Promise.all 中如果提前拒绝,其他 Promise 仍可能继续执行,但结果被忽略。
- 【易错点 3】使用 allSettled 时,若不检查 status 而直接取 value,可能得到 undefined。