在项目中会遇到,比如有多个select列表的数据,为了简化高效我们的代码,我们会用到promise.all(),进行统一处理返回。
但是promise.all也存在一个问题,当遇到reject时,我们调用promise.all,就会直接返回到catch里面,并且catch中只会返回第一个变成rejected的promise的错误。假如我们有三个接口,其中一个接口挂了,这时我们另外两个接口也就取不到数据了,很明显,这不是我们想要的。
const promise1 = Promise.resolve('promise1');
const promise2 = Promise.reject('promise2')
const promise3 = Promise.resolve('promise3')
const promises = [promise1, promise2, promise3];
Promise.all(promises).then((results) => {
console.log(results);
}).catch(err => {
console.log(err); // promise2
})
那如何解决这个问题呢???
Array.map遍历promise数组,调用item.catch(),当数组中有接口reject时,catch住结果直接返回,这样失败的结果也可以当做成功处理。
function promiseAll(...arg) {
return new Promise((resolve, reject) => {
const promiseAll = [...arg]
.flat(Infinity)
.map(
(item) =>
(Object.prototype.toString.call(item) ===
"[object Promise]" &&
item.catch((e) => e)) ||
item
);
Promise.all(promiseAll)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
ES11新特性,加入了Promise.allSettled,是一个新的 Promise 组合器,不像all、race一样具有短路特性。
相同点:都可以接受一组promise实例作为参数,并包装返回成一个新的promise实例
不同点:无论是成功状态或者是失败状态,它都会返回一个 promise。
Promise.allSettled(promises).then(res => {
console.log(res);
})
[
{ status: 'fulfilled', value: 'promise1' },
{ status: 'rejected', reason: 'promise2' },
{ status: 'fulfilled', value: 'promise3' }
]
status:状态 value:值 reason:原因