场景举例:
在前端页面首次加载时,前端页面都需要一次性加载多个接口,此时前端同学都会用到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);
});
此时结果如图所示,前端可以正常拿到结果,并做对应的逻辑渲染;
但是,当有个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);
});
如下图所示:
可以看到,只要有一个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);
});
结果如下图所示:
通过以上改造,正确和异常的内容均可返回。