这四个 Promise 静态方法是异步编程的核心工具,核心区别集中在 “成功 / 失败条件” 和 “返回结果形式” 上。
核心结论:all 全成才成,allSettled 无论成败都等所有结果,race 比谁先完成(无论成败),any 比谁先成功(忽略失败)。
一、核心区别对比(表格清晰呈现)
| 方法 | 成功条件 | 失败条件 | 返回结果(成功时) | 关键特性 |
|---|---|---|---|---|
Promise.all(iterable) | 所有 Promise 都 fulfilled | 任意一个 Promise rejected | 所有成功结果组成的数组(顺序与输入一致) | 一败俱败,严格顺序 |
Promise.allSettled(iterable) | 所有 Promise 都 settled(无论成败) | 无(始终返回成功) | 所有结果组成的数组(每个元素含 status 和 value/reason) | 等待所有结果,不关心成败 |
Promise.race(iterable) | 第一个完成的 Promise 是 fulfilled | 第一个完成的 Promise 是 rejected | 第一个完成的单个结果(成功值) | 比速度,先到先得(无论成败) |
Promise.any(iterable) | 任意一个 Promise 是 fulfilled | 所有 Promise 都 rejected | 第一个成功的单个结果(成功值) | 一胜即胜,忽略失败 |
二、逐个拆解(结合场景 + 示例)
1. Promise.all ():“所有任务都完成,才算成功”
-
核心场景:需要所有异步结果才能继续(如表单多字段校验、并行加载多个依赖资源)。
-
示例:
javascript
运行
const loadA = Promise.resolve('资源A'); const loadB = Promise.resolve('资源B'); const loadC = Promise.reject('资源C加载失败'); Promise.all([loadA, loadB, loadC]) .then(res => console.log(res)) // 不执行(因loadC失败) .catch(err => console.log(err)); // 输出:资源C加载失败 -
关键:只要有一个失败,立即终止,返回第一个失败原因。
2. Promise.allSettled ():“不管成功失败,我要知道所有结果”
-
核心场景:需要统计所有异步操作的最终状态(如批量任务执行后,统计成功 / 失败数量)。
-
示例:
javascript
运行
Promise.allSettled([loadA, loadB, loadC]) .then(res => console.log(res)); // 输出结果(每个元素含状态和结果): // [ // { status: 'fulfilled', value: '资源A' }, // { status: 'fulfilled', value: '资源B' }, // { status: 'rejected', reason: '资源C加载失败' } // ] -
关键:始终成功返回,结果数组与输入顺序一致,需手动判断每个任务的状态。
3. Promise.race ():“谁先完成,就用谁的结果”
-
核心场景:超时控制(如接口请求超时后,返回 “超时提示”)。
-
示例:
javascript
运行
const request = fetch('https://api.example.com'); const timeout = new Promise((_, reject) => setTimeout(() => reject('请求超时'), 3000) ); Promise.race([request, timeout]) .then(res => console.log(res)) // 3秒内请求成功则执行 .catch(err => console.log(err)); // 3秒内未完成则输出“请求超时” -
关键:只看 “完成顺序”,不看 “成功失败”—— 第一个完成的是失败,整体就失败。
4. Promise.any ():“谁先成功,就用谁的结果”
-
核心场景:多源备份(如多 CDN 加载图片,取第一个成功加载的)。
-
示例:
javascript
运行
const cdn1 = Promise.reject('CDN1失败'); const cdn2 = Promise.resolve('CDN2加载成功'); const cdn3 = Promise.resolve('CDN3加载成功'); Promise.any([cdn1, cdn2, cdn3]) .then(res => console.log(res)) // 输出:CDN2加载成功(第一个成功) .catch(err => console.log(err)); // 所有失败才执行 -
关键:忽略失败任务,只等第一个成功结果;所有都失败时,返回
AggregateError(含所有失败原因)。
三、关键易混点区分
-
allvsallSettled:all追求 “全成”,失败则终止;allSettled追求 “全结果”,无论成败都等待。
-
racevsany:race比 “完成速度”,第一个完成的是失败就整体失败;any比 “成功速度”,会跳过失败任务,只等第一个成功。