簡體   English   中英

與多個 map function 調用一起使用時,Nodejs Promise.all 未捕獲錯誤/承諾拒絕

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM