文章目录
一、共同点
- 这些方法的参数都接收一个
promise
的iterable
类型(Array,Map,Set
都属于ES6
的iterable
类型)的输入 - 这些方法都返回一个
promise
的示例
二、各方法之间的区别
2.1返回的promise
状态改变时机不同
-
all
当所有的输入promise
实例的状态都改变为fulfilled
状态,新的promise
实例才是fulfilled
状态,返回所有输入promise
实例的resolve value
数组;
如果有一个promise
实例的状态是rejected
,则新的promise
实例的状态就是rejected
,返回第一个promise reject的reason
-
allSettled
返回所有promise实例执行的数组,格式如下:
[
{status: "fulfilled", value: 1},
{status: "rejected", reason: "error"},
{status: "rejected", reason: 2},
]
- any
返回promise
数组中最先变成fulfilled
实例的value
,如果,所有输入的promise
实例的状态都是rejected
, 返回all promise were rejected
- race
返回最先执行结束的promise
的value
或者reason
,不论状态是rejected
还是fulfilled
2.2 返回的promise实例的终值或者拒因不同
all
方法返回的promise
实例终值是一个数组,数组的成员是所有输入的promise
实例的终值,并将会按照参数内的promise
顺序排列,而不是promise的完成顺序;拒因是输入的promise
实例钟第一个状态变为rejected
的拒因- allSettled方法返回的
promise
实例终值也是一个数组,顺序同promise
的输入顺序一致,,其中每个成员在输入promise
为resolved
状态时为{status:‘fulfilled’, value:同一个终值}
,rejected 状态时为{status:‘rejected’, reason:同一个拒因}
。
2,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))
三、手写实现
3.1 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出去
reject(err));
}
})
}
测试:
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {resolve(1)}, 1000)
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {resolve(2)}, 2000)
})
const p3= new Promise((resolve, reject) => {
setTimeout(() => {resolve(3)}, 3000)
})
_all([p1, p2, p3]).then(res=>console.log(res)).catch(err=> console.log(err));//三秒后打印[1,2,3]
3.2 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);
}
})
}
})
}
测试:_allSettled([p1, p2, p3]).then(res => console.log(res)).catch(err => console.log(err));
3.3 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)
}
})
}
})
}
3.4 promise.race
function _race (promises) {
return new Promise((resolve, reject) => {
for(p of promises) {
Promise.resolve(p).then(res => {
resolve(res)
}).catch(err=> reject(err))
}
})
}
3.5 Promise.prototype.finally
Promise.prototype._finally = function (cb) {
// 谁调用finally,this就是谁
return this.then(
// 不管调用finally的promise是什么状态,都执行回调函数
value => Promise.resolve(cb()),
error => Promise.reject(cb())
)
}
明白各个方法的作用,理清楚思路,代码实现真的很简单。