Promise.allSettled 了解吗?动手实现以下 Promise.allSettled
Promise.allSettled(iterable) 概念
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettedPromise = Promise.allSettled([resolved, rejected]);
allSettedPromise.then(function (results) {
console.log(results);
});
// [{
// status: "fulfilled",
// value: 42
// }, {
// status: "rejected",
// reason: -1
// }]
1、Promise.allSettled() 方法接受一组 Promise 实例作为参数,返回一个新的 Promise 实例
2、只有等到所有这些参数实例都返回结果,不管是 fulfilled 状态 还是 rejected 状态,包装实例才会结束
3、返回的新 Promise 实例,一旦结束,状态总是 fulfilled,不会变成 rejected
4、新的 Promise 实例给监听函数传递一个数组 results 。该数组的每个成员都是一个对象,对应传入 Promise.allSettled 的 Promise 实例。每个对象都有 status 属性,对应着 fulfilled 和 rejected 。fulfilled 时,对象有 value 属性,rejected 时,有 reason 属性,对应着两种状态的返回值。
5、有时候我们不关心异步操作的结果,只关心这些操作有没有结束时,这个方法会比较有用。
手写实现
//定义状态和返回结果
const formatSettledResult = (success,value)=>
success
? {status:'fulfilled',value}
: {status:'rejected',reason:value};
//定义all_settled
Promise.all_settled = function(iterators){
//转为数组
const promises = Array.from(iterators);
//传入Promise 实例的数量
const num = promises.length;
//返回的结果数组
const resultList = new Array(num);
//对要处理的传入参数的promise实例的计数
let resultNum = 0;
//返回一个Promise实例,由于allSettled 总返回 fulfilled 状态所以这里仅在 resolve 回调中处理
return new Promise((resolve)=>{
//遍历传入的promise实例数组
promises.forEach((promise,index)=>{
//用Promise.resolve包裹
Promise.resolve(promise)
.then(value=>{
//fulfilled状态,结果数组中添加每个实例的状态
resultList[index] = formatSettledResult(true,value);
if(++resultNum === num){
//实例处理完成,返回结果数组
resolve(resultList);
}
})
.catch(error=>{
//rejected状态,结果数组中添加每个实例的状态
resultList[index] = formatSettledResult(false,error);
if(++resultNum === num){
//实例处理完成,返回结果数组
resolve(resultList);
}
})
})
})
}
//测试
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettedPromise = Promise.all_settled([resolved, rejected]);
allSettedPromise.then(function (results) {
console.log(results);
});