我正在使用 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,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`);
}
运行时输出
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