最近工作中使用到Promise的情况比较多,Promise.all方法也用的不少,下面来总结一下使用的几种情况
我们先来看一下promise.all对错误的处理
Promise.all([new Promise((resolve,reject)=>{
reject(666)
})]).catch(err=>{
console.log(err); //666
})
我们可以看到:内部的promise触发了reject路线,而且并没有写catch,但是并没有报错,而是被外界promise.all的catch捕捉到了错误并打印出来,所以对于promise.all的catch,可以看作try,catch冒泡处理错误。
经测试,一个promise处理内部promise的catch并不行
明确上面内容后,我们可以把场景分为几种情况
1.错误的promise没catch,promise.all写catch,如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
})
Promise.all([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log('res');
console.log(res);
}).catch(err=>{
console.log('err');// err
console.log(err); // 222
})
由打印内容可知:产生错误的那个promise并没有处理错误,但是promise.all捕捉到错误并进行处理
2.错误的promise catch,promise.all无catch,如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
}).catch(err=>{
})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
}).catch(err => {
return 666
})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
}).catch(err => {
})
Promise.all([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log('res'); //res
console.log(res); //[ 111, 666, 333 ]
})
我们可以看到,promise.all传的多个promise中有执行reject的,但是promise.all依旧执行then,这是因为catch处理的终归是报错,内部promise被自己的catch拦截下来了,则promise.all检测不到错误自然会执行then,值得一提的是每个promise的最后一次then/catch可以看作其返回值(特别是用await 获取的时候需注意)
3.错误的promise 有catch,promise.all有catch,如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
}).catch(err=>{
})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
}).catch(err => {
})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
}).catch(err => {
})
Promise.all([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log('res');
console.log(res);
}).catch(err=>{
console.log('err');
console.log(err); //[ 111, undefined, 333 ]
})
结果基本同上,注意此次代码promise的catch中没有返回值,所以promise.all获取了一个undefined
3.错误的promise 无catch,promise.all无catch,如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
})
Promise.all([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log('res');
console.log(res);
})
不出所料,代码执行后报错如下
总结:若想要每个传入的promise都返回值,不管是否报错,则需要每个promise都单独写好自己的catch,若只想筛取执行成功的promise,可以参考如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
}).catch(err=>{})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
}).catch(err=>{})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
}).catch(err=>{})
Promise.all([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log(Array.prototype.filter.call(res,Boolean)); //[ 111, 333 ]
})
使用Array.prototype.filter.call是因为res可能为类数组
除此之外,也可以使用promise的另一个方法:Promise.allSettled , 如下
const promiseOne = new Promise((resolve, reject) => {
resolve(111)
})
const promiseTwo = new Promise((resolve, reject) => {
reject(222)
})
const promiseThree = new Promise((resolve, reject) => {
resolve(333)
})
Promise.allSettled ([promiseOne, promiseTwo,promiseThree]).then(res=>{
console.log(Array.prototype.filter.call(res,Boolean));
return Array.prototype.filter.call(res,Boolean)
})
//[
// { status: 'fulfilled', value: 111 },
// { status: 'fulfilled', value: undefined },
// { status: 'fulfilled', value: 333 }
//]
可以看到:不管出错的promise是否有自己的catch,Promise.allSettled都会返回对应截取值