Promise.all和Promise.race的介绍
- 相似点:
- 这两个都是
Promise的方法,并且传入的参数都是一个Promise的数组。 - 都会返回一个
Promise实例
- 这两个都是
- 区别:
- all: 传入的所有
Promise最终都转化为fulfilled态时,则会执行resolve回调,并将返回值是的所有的Promise的resolve的回调的value的数组。其中一个任何Promise为reject状态时,则返回的Promise的状态更改为rejected。 - race: 传入的所有
Promise其中任何一个有状态转化为fulfilled或者rejected,则将执行对应的回调。
- all: 传入的所有
如果觉得表述模糊不清,请点击MDN的Promise介绍页面
示例代码
promise.all。以下代码涵盖all中Promise可能出现的各种状态
//p1:0.5s后转化为fullfilled状态
let p1 = new Promise((res,rej) => {
setTimeout(()=>{
res("p1调用成功")
},500)
})
//p2: 直接转化为res状态
let p2 = new Promise((res,rej) => {
res("p2调用成功")
})
//p3: 1s后转化为rejected状态
let p3 = new Promise((res,rej) => {
setTimeout(()=>{
rej("p3失败了...")
},1000)
})
//p4: 2s后转化为rejected状态
let p4 = new Promise((res,rej) => {
setTimeout(()=>{
rej("p4失败了...")
},2000)
})
// 传入p1,p2
Promise.all([p1,p2]).then(res =>{
console.log(res); // ['p1调用成功','p2调用成功']
}).catch(rej => {
console.log(rej);
})
//传入p3
Promise.all([p1,p2,p3]).then((res,rej) => {
console.log(res);
}).catch(rej => {
console.log(rej); //p3失败了...
})
//传入p4
Promise.all([p1,p2,p3,p4]).then((res,rej) => {
console.log(res);
}).catch(rej => {
console.log(rej); //p3失败了...
})
promise.race。以下代码涵盖race中Promise可能出现的各种状态
//p1:0.5s后转化为fullfilled状态
let p1 = new Promise((res,rej) => {
setTimeout(()=>{
res("p1调用成功")
},500)
})
//p2: 直接转化为res状态
let p2 = new Promise((res,rej) => {
res("p2调用成功")
})
//p3: 1s后转化为rejected状态
let p3 = new Promise((res,rej) => {
setTimeout(()=>{
rej("p3失败了...")
},1000)
})
//p4: 2s后转化为rejected状态
let p4 = new Promise((res,rej) => {
setTimeout(()=>{
rej("p4失败了...")
},2000)
})
//传入p1,p2
Promise.race([p1,p2]).then(res =>{
console.log(res) //p2调用成功
})
//传入p1,p3
Promise.race([p1,p3]).then(res => {
console.log(res) //p1调用成功
}).catch(rej => {
console.log(rej)
})
//传入p3,p4
Promise.race([p3,p4]).then(res => {
console.log(res)
}).catch(rej => {
console.log(rej) //p3失败了...
})
面试考点
看到这里相信你应该对这两个方法有一定的理解,面试会问那些相关的问题呢?
使用场景
当用户想要得到的是多个异步结果合并到一起时应该使用all
当我们想要控制某一个异步操作的时间时,就可以用定时器和race来进行实现。
传入空数组
当我们的all和race传入的是空数组时,会有出现什么状况呢?
- all: 感谢楼下评论的提醒,后来去看了MDN上promise.all的讲解,发现是返回一个状态是resovle的promise对象。
- race: 返回的
Promise会一直保持在pending状态。
手写实现
Promise.all
function all(arr){
//返回一个promise
return new Promise((res,rej) => {
let length = arr.length //传入的promise的个数
let count = 0 //进入fullfilled的promise个数
const result = [] //创建一个等长的数组,放置结果
// 当传递是一个空数组,返回一个为fulfilled状态的promise
if(arr.length === 0 ) {
return new Promise.resolve(arr)
}
for(let i = 0; i < arr.length; i++){
arr[i].then(resolve => {
result[i] = resolve //将每次结果保存在result数组中
count ++ //个数加1
//是否所有的promise都进入fullfilled状态
if(count === length){
res(result) //返回结果
}
}).catch(e => {
rej(e) //如果有错误则直接结束循环,并返回错误
})
}
})
}
Promise.race
function race(arr){
return new Promise((res,rej) => {
for(let i = 0; i < arr.length; i++){
arr[i].then(resolve => {
res(resolve) //某一promise完成后直接返回其值
}).catch(e => {
rej(e) //如果有错误则直接结束循环,并返回错误
})
}
})
}