Node.js 未处理的PromisejectionWarning,后跟PromisejectionHandleWarning

Node.js 未处理的PromisejectionWarning,后跟PromisejectionHandleWarning,node.js,es6-promise,Node.js,Es6 Promise,下面的代码为p2提供了一个未处理的PromisejectionWarning,尽管p2上的错误被显式处理 function syncFunctionReturnsPromise(val) { return new Promise((r,x)=> { setTimeout(()=> { if (val) { r('ok'); } else { x('not ok'); } }, val?1000:

下面的代码为p2提供了一个未处理的PromisejectionWarning,尽管p2上的错误被显式处理

function syncFunctionReturnsPromise(val)
{
  return new Promise((r,x)=> {
    setTimeout(()=> {
      if (val) { 
        r('ok');
      } else {
        x('not ok');
      }
    }, val?1000:500);
  });
}

async function test(){
  let p1 = syncFunctionReturnsPromise(true);
  let p2 = syncFunctionReturnsPromise(false); 
  await p1.catch(ex => console.warn('warning:', ex));  //errors in these 2 promises
  await p2.catch(ex => console.warn('warning:', ex));  //are not the end of the world
  console.log('doOtherStuff');
}
test();
输出如下所示:

(node:9056) UnhandledPromiseRejectionWarning: not ok
(node:9056) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9056) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
warning: not ok
doOtherStuff
(node:9056) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)

我现在还不清楚为什么会这样,这是因为在处理程序连接到p2之前,第一个wait会同步等待。但是p2在p1完成之前失败

所以节点检测到p2失败,没有任何错误处理

注意:在node的更高版本中,这可能会导致程序终止,而不仅仅是警告

修复方法是在等待之前附加处理程序

async function test(){
  let p1 = syncFunctionReturnsPromise(true);
  let p2 = syncFunctionReturnsPromise(false); 
  p1 = p1.catch(ex => console.warn('warning:', ex));  //errors in these 2 promises
  p2 = p2.catch(ex => console.warn('warning:', ex));  //are not the end of the world

  await p1;
  await p2;
  console.log('doOtherStuff');
}
显然,您可以将其内联到声明中,尽管在我的现实世界代码中,它更整洁,作为单独的行。

这里是另一种方式:

async function test(){
  let p1 =  await syncFunctionReturnsPromise(true)
                .catch(ex => console.warn('warning:', ex));
  let p2 =  await syncFunctionReturnsPromise(false)
                .catch(ex => console.warn('warning:', ex)); 
  console.log('doOtherStuff');
}

在写这个问题和答案时,我意识到实际上已经有类似的问题了,但我的谷歌搜索没有显示出来。所以我还是提交了这个,希望它能帮助别人。你把它改成了顺序的而不是并行的。这是不对等的,有理由将其与之平行。谢谢。互联网上唯一合理的解释。