# 10. Promise的 all/any/race/allSettled 方法的区别
在实现 Promise.all 方法之前,我们首先要知道 Promise.all 的功能和特点,因为在清楚了 Promise.all 功能和特点的情况下,我们才能进一步去写实现。
# 1. 返回的promise状态改变时机不同
all
当所有的输入promise实例的状态都改变为fulfilled状态,新的promise实例才是fulfilled状态,返回所有输入promise实例的resolve value数组; 如果有一个promise实例的状态是rejected,则新的promise实例的状态就是rejected,返回第一个promise reject的reasonallSettled
返回所有promise实例执行的数组,格式如下:
[
{status: "fulfilled", value: 1},
{status: "rejected", reason: "error"},
{status: "rejected", reason: 2},
]
any
返回promise数组中最先变成fulfilled实例的value,如果所有输入的promise实例的状态都是rejected, 返回all promise were rejectedrace
返回最先执行结束的promise的value或者reason,不论状态是rejected还是fulfilled
# 2. 返回的promise实例的终值或者拒因不同
- all 方法返回的promise实例终值是一个数组,数组的成员是所有输入的promise实例的终值,并将会按照参数内的promise顺序排列,而不是promise的完成顺序;拒因是输入的promise实例钟第一个状态变为rejected的拒因。
- allSettled 方法返回的promise实例终值也是一个数组,顺序同promise的输入顺序一致,其中每个成员在输入 promise 为 resolved 状态时为 {status:'fulfilled', value:同一个终值},rejected 状态时为 {status:'rejected', reason:同一个拒因}。
# 3. 参数为空迭代对象时,返回值不同
- all 方法会同步的返回一个已完成状态的promise, 终值值一个空数组
- allSettled 方法和all表现形式相同
- any 方法会同步的返回一个失败状态的promise,拒因是一个AggregateError对象
- race 方法返回一个pending状态的promise
测试:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 500)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p2 error')
}, 1000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('p2 error')
}, 1500)
})
Promise.all([p1, p2, p3])
.then(res => console.log('then', res))
.catch(err => console.log('catch', err))//catch p2 error
Promise.race([p1, p2, p3])
.then(res => console.log('then', res))//then 1
.catch(err => console.log('catch', err))
Promise.allSettled([p1, p2, p3])
.then(res => console.log('then', res))//数组
.catch(err => console.log('catch', err))
Promise.any([p1, p2, p3])
.then(res => console.log('then', res))//then 1
.catch(err => console.log('catch', err))
Promise.all([])
.then(res => console.log('then', res))//[]
.catch(err => console.log('catch', err))
Promise.any([])
.then(res => console.log('then', res))
.catch(err => console.log('catch', err))//AggregateError: All promises were rejected
Promise.allSettled([])
.then(res => console.log('then', res))//[]
.catch(err => console.log('catch', err))
Promise.race([])//pengding状态不输出结果
.then(res => console.log('then', res))
.catch(err => console.log('catch', err))
# 手写实现
- promise.all
function _all (promises) {
// count 计数器,与len比较,判断是否所有的promise都已经成功了;
// result 用于存放成功的结果。
let count=0, len=promises.length, result=[];
return new Promise((resolve, reject) => {
// 依次判断传入的promise实例是否成功
for(let p of promises) {
Promise.resolve(p).then(res => {
result[count] = res;
count++;
if(count === len) {
//相等,说明所有的promise实例都成功了, 才可以resolve结果
resolve(result);
}
}).catch(err => reject(err)); //只要有一个失败了就reject出去
}
})
}
- promise.allSettled
function _allSettled (promises) {
let result=[],len=promises.length; count=0;
return new Promise((resolve, reject) => {
for(let p of promises) {
Promise.resolve(p).then(res => {
result[count] ={
status:'fulfilled',
result:res
}
count++;
if(count === len) {
resolve(result)
}
}).catch(err => {
result[count] ={
status:'rejected',
result:err
}
count++;
if(count === len) {
reject(result);
}
})
}
})
}
- promise.any
function _any (promises) {
let result =[],len=promises.length, count=0;
return new Promise((resolve, reject) => {
for(let p of promises) {
Promise.resolve(p).then(res => {
resolve(res);
}).catch(err => {
result[count]=err;
count++;
if(count===len){
reject(result)
}
})
}
})
}
- promise.race
function _race (promises) {
return new Promise((resolve, reject) => {
for(let p of promises) {
Promise.resolve(p).then(res => {
resolve(res)
}).catch(err=> reject(err))
}
})
}