【问题标题】:Why promise reject does not handle an error为什么承诺拒绝不处理错误
【发布时间】:2021-12-22 10:46:49
【问题描述】:

我正在使用 nodejs request 包(2.88 版本)和 node v10.24.1

如果没有指定 url,下面的 Promise 不会处理错误。我收到了UnhandledPromiseRejectionWarning,从request package 源我可以看到针对该案例引发的异常。

如果我删除 async 关键字一切正常,并且拒绝处理。

return new Promise(async (resolve, reject) => {
   request(uri: url).on('error', err => {
      reject();
   }).on('response', response => {
      resolve();
   });
});

你能解释一下发生了什么吗?请求的异常可能在拒绝实际触发之前完成。请提供任何详细信息。

【问题讨论】:

  • 您传递给new Promise() 的函数应该永远是异步的,但如果是......我不明白为什么会失败。行为应该是相似的。
  • 所以也许您可以分享一个更完整的示例来演示错误处理不起作用。但只是重复一遍,如果这只是一个学术练习,那就太酷了!但是不要在这里使用异步
  • @Evert,外部函数是异步的。 error 上的所有内容都处理得很好,但如果没有指定 url,它就会失败。如果我只是在 promise 中添加 try/catch,它也可以正常工作,但我意识到这是错误的,不应该那样。
  • 啊,这很有道理!我会回答这个问题。

标签: node.js promise


【解决方案1】:

当您将函数传递给new Promise 时,该函数会立即执行。

这里没有魔法,为了说明,new Promise() 的构造函数可能看起来有点像这样:

class Promise {
  constructor(executor) {
    executor(this.resolveFunction, this.rejectFunction); 
  }
}

所以这个例子:

new Promise(() => {
  console.log(1);
});
console.log(2);

输出:

1
2

这很重要,因为如果您将某些内容传递给new Promise 并引发异常,这也会立即发生:

new Promise((res, rej) => {
  throw new Error('foo');
});

这里抛出的错误不会导致promise被拒绝,它完全阻止了new Promise()成功。不返回任何承诺,并且在调用 new Promise()outer 函数中抛出异常。

但是,当您传递异步函数时,这会发生故障:

new Promise(async (res, rej) => {
  throw new Error('foo');
});

由于异步函数的工作方式,在设置new Promise() 期间不会抛出此错误,但您传递的异步函数将异步处理错误并返回一个被拒绝的承诺,即@ 987654332@不知道怎么处理。

这与自己直接调用异步函数而不处理错误没有什么不同:

(async () => {
  throw new Error('foo');
})();

所以事情失败的原因与new Promise() 的关系不大,而更多地与异步函数的一般工作原理有关。

对于未来的读者来说,这只是最后一次,您永远不应该将 async 执行程序传递给 new Promise(),因为:

  • 您需要async 的唯一原因是您可以使用await
  • await 仅适用于承诺。
  • 如果你已经有一个你想要await的承诺,你不需要new Promise()开始,因为new Promise的主要用例是转换一些东西在做的事情中使用承诺。

【讨论】:

    猜你喜欢
    • 2018-07-04
    • 2020-02-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多