Promise.all & Promise.allSettled

438 阅读1分钟

在项目中会遇到,比如有多个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:原因