Promise.all如何把正确和错误的值都返回

194 阅读1分钟

场景举例:

在前端页面首次加载时,前端页面都需要一次性加载多个接口,此时前端同学都会用到Promise.all,如果Promise返回值都是正常的话,使用该方案,是没有问题的,我们先来个正常的demo

const p1 = Promise.resolve("正常返回 aa");
const p2 = Promise.resolve("正常返回 bb");
const p3 = Promise.reject("正常返回 cc");
const p4 = Promise.resolve("正常返回 dd");
Promise.all([p1, p2, p3, p4]).then(res=> {
    console.log("res====>>>>", res);
});

此时结果如图所示,前端可以正常拿到结果,并做对应的逻辑渲染;

image.png

但是,当有个Promise走的异常场景时,则会遇到如下问题,请看下方代码:

const p1 = Promise.resolve("正常返回 aa");
const p2 = Promise.resolve("正常返回 bb");
const p3 = Promise.reject("异常返回 cc");
const p4 = Promise.resolve("正常返回 dd");
Promise.all([p1, p2, p3, p4]).then(res=> {
    console.log("res====>>>>", res);
});

如下图所示:

image.png

可以看到,只要有一个Promise走异常了,其他的都会被阻塞,这样就会导致页面其它的模块无法成功渲染。

如何优化

只需在Promise.all([])的列表中,先对所有子item进行遍历,并把所有正常和异常的内容均返回,代码如下

const p1 = Promise.resolve("正常返回 aa");
const p2 = Promise.resolve("正常返回 bb");
const p3 = Promise.reject("异常返回 cc");
const p4 = Promise.resolve("正常返回 dd");
Promise.all([p1, p2, p3, p4].map((item) => {
    return item.then((res)=>{
        return res;
    }).catch((err)=> {
        return err;
    })
})).then(res=> {
    console.log("res====>>>>", res);
});

结果如下图所示:

image.png

通过以上改造,正确和异常的内容均可返回。