繁体   English   中英

是什么确定在node.js(控制台/脚本)中未处理承诺拒绝?

[英]What determines that a promise rejection is unhandled in node.js (console/script)?

如果我不得不简化的话,JavaScript承诺对我来说是“ 稍后通过.then()方法安排对内容进行操作的方式”。

在我的终端中执行以下操作之后:

BASE$> node
> var promise = Promise.reject("reason 42");

因此,我很惊讶地看到以下结果:

> (node:8783) UnhandledPromiseRejectionWarning: reason 42
(node:8783) 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:8783) [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.

因为我正要写。

> promise.catch(console.log);

激发这个问题的是:
我可以合理地确定node.js仅发出此警告(并且威胁“将来我将完全保释”,因为代码在node.js控制台/ REPL中逐步运行)?

node.js如何已经得出结论,即未处理承诺拒绝?

因此,我对以下内容进行了测试,以使其有所不同

  1. 在一次REPL迭代中结合“相同代码”的评估:
    var promise = Promise.reject("reason 42"); promise.catch(console.log);
  2. 评估包含内容的文件(例如tmp.js )中的“相同代码”
      var promise = Promise.reject(“原因42”) \n promise.catch(console.log);`)\n
    通过node tmp.js

两者都产生了预期的输出“ reason 42 ”,但未显示任何警告,如上所述。

因此,如何解决? 我的假设是否可以确认,在节点控制台REPL未处理的诺言的确定,是否反映了每个REPL循环迭代的终点?

为了使承诺拒绝被视为已处理,应将其与catchthen在同一刻度上带有2个自变量链接在一起。

这将导致UnhandledPromiseRejectionWarning

var promise = Promise.reject("reason 42");

setTimeout(() => {
  promise.catch(console.error);
});

这不会导致UnhandledPromiseRejectionWarning

var promise = Promise.reject("reason 42");
promise.catch(console.error);

Node.js REPL中异步评估的行会导致它们之间的延迟。 为了按照编写的顺序同步评估行,可以使用编辑器模式 或者可以编写代码以明确地将其评估为一个块:

;{
var promise = Promise.reject("reason 42");
promise.catch(console.error);
}

或IIFE:

(() => {
var promise = Promise.reject("reason 42");
promise.catch(console.error);
})()

我想扩展@estus答案,尤其是第一句话:

为了使承诺拒绝被视为已处理,应将其与catch或随后在同一刻度上带有2个自变量链接在一起。

我不同意这一点。 我争辩说,在thencatch处调用的每个promise都可以, 但是在调用这些方法时,您将创建新的Promises,而它们只是继承了问题。

我们经常谈论承诺链,但是实际上它是一棵树,因为您可以从同一个“父”分支多个“子承诺”,而错误会影响所有这些。

const root = Promise.reject("reason 42");

const a = root.then(value => value*2)
              .then(...);

const b = root.then(value => value*3)
              .then(...);

因此,您建立了承诺链/树状结构; 发生错误。 错误会传播到该树中的子承诺中,...如果该(或任何其他)错误达到了任何叶子承诺(没有被沿行捕获),您将获得UnhandledPromiseRejectionWarning

您可以用一百万种承诺来做,以及如何将它们链接/分支以及如何/在哪里捕捉错误,...所以我可以给您最好的总结:

由于Promises都是关于时间的,因此您有时间直到Error到达链的末尾才能catch它。

我是否可以合理地确定node.js仅发出此警告(并且威胁“将来我将完全保释”,因为代码在node.js控制台中逐步运行)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM