如何解决与多个映射函数调用一起使用时,Nodejs Promise.all 不会捕获错误/承诺拒绝
我使用 Promise.all 来运行两个单独的函数,它们本身就是在 Promise.all 中多次运行一个函数的映射。
async function nonBlockingWithMapAndarray(): Promise<any> {
let arr = [100,200,150];
let arr2 = [500,1000,300]; // <--- value of 1000 causes an error to be thrown
console.log(`nonBlockingWithMapAndarray: starting...`);
const pa = await Promise.all([
await iterateArrayAndCall(arr),await iterateArrayAndCall(arr2) // <--- This throws an error
])
.then( (data) => {
console.log(`nonBlockingWithMapAndarray: In then...`);
})
.catch((err) => { // <-- This should catch the error but does not,instead the error goes up to main which calls nonBlockingWithMapAndarray()
console.log('nonBlockingWithMapAndarray: In catch',err);
});
console.log(`nonBlockingWithMapAndarray: Finished`);
return pa;
}
当没有抛出错误时,我的解决方案可以正常工作。但是,如果抛出错误,Promise.all 的捕获不会捕获错误,而是传播到主调用应用程序。
在这段代码中,第二个函数调用 iterateArrayAndCall(arr2)
抛出了一个错误。但它不会被 catch
上的 Promise.all
捕获。
任何帮助将不胜感激。完整代码如下...
bootstrap();
async function bootstrap() {
let res;
try {
res = await nonBlockingWithMapAndarray();
} catch (err) {
console.log('Main: In catch'); // <-- This is where the error is caught
}
}
async function nonBlockingWithMapAndarray(): Promise<any> {
let arr = [100,300]; // <--- value of 1000 throws an error
console.log(`nonBlockingWithMapAndarray: starting...`);
const pa = await Promise.all([
await iterateArrayAndCall(arr),await iterateArrayAndCall(arr2) // <--- This throws an error
])
.then( (data) => {
console.log(`nonBlockingWithMapAndarray: In then...`);
})
.catch((err) => { // <-- This should catch the error but does not
console.log('nonBlockingWithMapAndarray: In catch',err);
});
console.log(`nonBlockingWithMapAndarray: Finished`);
return pa;
}
async function iterateArrayAndCall(arr: any) : Promise<any> {
return await Promise.all(
arr.map( async (element) => {
await delayAndGetRandomPromWithError(element); //If element is 1000 an error will be generated
})
)
.then((data) => {
console.log(`iterateArrayAndCall: in then...`);
})
.catch((err) => {
console.log(`iterateArrayAndCall: in catch`);
throw new Error('Failed in iterateArrayAndCall');
// Also tried:
// return Promise.reject();
// return err
});
}
async function delayAndGetRandomPromWithError(ms): Promise<number> {
console.log(`MS start :${ms}`);
if( ms === 1000 ) {
throw new Error('1000 so throw error...');
}
const p: Promise<number> = new Promise(resolve =>
setTimeout(() => {
const val: number = Math.trunc(Math.random() * 100);
console.log(`MS finish :${ms}`);
resolve(val);
},ms
));
return p;
};
async function throwOne() {
console.log(`Am I blocking?`);
throw new Error(`Test error`);
}
运行时输出
nonBlockingWithMapAndarray: starting...
MS start :100
MS start :200
MS start :150
MS finish :100
MS finish :150
MS finish :200
iterateArrayAndCall: in then...
MS start :500
MS start :1000
MS start :300
iterateArrayAndCall: in catch
Main: In catch <--- I expect to see this here instead .... 'nonBlockingWithMapAndarray: In catch'
MS finish :300
MS finish :500
解决方法
可能您的 iterateArrayAndCall
直接在其自己的堆栈(而不是异步堆栈)上抛出,因此错误由其底层堆栈 (nonBlockingWithMapAndArray) 捕获:
function iterateArrayAndCall () { throw Error() }
Buf 如果你将调用包装到一个 promise 中,它将被 .catch
块捕获:
function iterateArrayAndCall () {
return new Promise((resolve,reject) => { throw Error() })
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。