romise.all()
作用
批量并发执行多个 Promise,全部成功才成功,任意一个失败立刻失败。接收一个 Promise 数组,返回一个新 Promise。
执行规则
-
所有 Promise 同时并发开始执行(不是串行排队)
-
全部 Promise 状态变为
fulfilled,返回的 Promise 才成功- 成功结果:结果数组,顺序和传入数组顺序保持一致,和谁先完成无关
-
只要任意一个 Promise
reject,Promise.all 立刻 reject,直接拿到这个失败原因,剩下还在执行的 Promise 会继续跑,但结果会被丢弃 -
如果数组里面不是 Promise(普通值),会直接当成成功的值放入结果数组
const p1 = Promise.resolve(10);
const p2 = Promise.resolve(20);
Promise.all([p1,p2]).then(res=>{
console.log(res); // [10,20]
})// 有一个失败
const p3 = Promise.reject('出错');
Promise.all([p1,p3]).catch(err=>{
console.log(err); // '出错',直接进入catch
})
使用场景
- 一次性请求多个独立接口,等所有接口全部返回数据再渲染页面(比如首页多个模块并行请求)
- 批量上传文件,等全部上传完成再提示上传成功
- 多个异步任务必须全部完成才能继续后续逻辑
缺点:一个崩,全军覆没。如果想要失败的任务不打断整体,用
Promise.allSettled
Promise.race()
作用
赛跑机制:谁最先改变状态(成功 / 失败),就采用谁的结果。
执行规则
-
多个 Promise 并发执行
-
第一个敲定状态(fulfilled /rejected)的 Promise,决定 race 的结果
- 最先成功:race 成功,拿到这个成功值
- 最先失败:race 失败,拿到这个错误信息
-
剩下还在执行的 Promise 依旧会继续执行,只是结果不再被接收
const pFast = new Promise(resolve=>setTimeout(()=>resolve('快的'),100));
const pSlow = new Promise(resolve=>setTimeout(()=>resolve('慢的'),1000));
Promise.race([pFast,pSlow]).then(res=>{
console.log(res); // "快的"
})// 最先失败的例子
const pErr = new Promise((resolve,reject)=>setTimeout(()=>reject('报错'),50));
Promise.race([pErr,pSlow]).catch(err=>console.log(err)) // 报错
使用场景
-
接口请求超时控制:请求 Promise 和一个定时器 Promise 赛跑,超时就抛出超时错误
function requestWithTimeout(reqPromise, time=3000){
const timer = new Promise((_,reject)=>{
setTimeout(()=>reject('请求超时'),time)
})
return Promise.race([reqPromise,timer])
} -
抢接口:多个相同请求通道,优先返回最快响应(极少场景)
一句话区分
Promise.all:全都成功才算成功,一个失败直接失败,收集全部结果Promise.race:谁先完成听谁的,不管成功失败,只拿第一名结果