[英]Nodejs Promise.all not catching error/promise rejection when used with multiple map function calls
我正在使用 Promise.all 來運行兩個單獨的函數,它們本身就是在 Promise.all 中運行 function 的地圖。
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 的捕獲不會捕獲錯誤,而是會傳播到主調用應用程序。
在此代碼中,第二個 function 調用iterateArrayAndCall(arr2)
會引發錯誤。 但它並沒有被Promise.all
上的catch
。
任何幫助,將不勝感激。 完整代碼如下...
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,200,150];
let arr2 = [500,1000,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`);
}
Output 運行時
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() }
如果將調用包裝到 promise 中,它將被.catch
塊捕獲:
function iterateArrayAndCall () {
return new Promise((resolve, reject) => { throw Error() })
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.