我应该避免异步处理Promise拒绝吗? [英] Should I refrain from handling Promise rejection asynchronously?

查看:1314
本文介绍了我应该避免异步处理Promise拒绝吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚安装了Node v7.2.0,并了解到以下代码:

I have just installed Node v7.2.0 and learned that the following code:

var prm = Promise.reject(new Error('fail'));

产生此消息:;

(node:4786) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: fail
(node:4786) 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 吞没。然而,我做了这个实验:

I understand the reasoning behind this as many programmers have probably experienced the frustration of an Error ending up being swallowed by a Promise. However then I did this experiment:

var prm = Promise.reject(new Error('fail'));

setTimeout(() => {
    prm.catch((err) => {
        console.log(err.message);
    })
},
0)

导致:

(node:4860) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: fail
(node:4860) 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.
(node:4860) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
fail

我基于 PromiseRejectionHandledWarning 假设处理 Promise 拒绝异步 /可能是坏事。

I on basis of the PromiseRejectionHandledWarning assume that handling a Promise rejection asynchronously is/might be a bad thing.

但为什么会这样?

推荐答案

我应该避免异步处理Promise拒绝吗?

这些警告有一个重要的目的,但要看看它是怎么回事作品见这些例子:

Those warnings serve an important purpose but to see how it all works see those examples:

试试这个:

process.on('unhandledRejection', () => {});
process.on('rejectionHandled', () => {});

var prm = Promise.reject(new Error('fail'));

setTimeout(() => {
    prm.catch((err) => {
        console.log(err.message);
    })
}, 0);

或者这个:

var prm = Promise.reject(new Error('fail'));
prm.catch(() => {});

setTimeout(() => {
    prm.catch((err) => {
        console.log(err.message);
    })
}, 0);

或者这个:

var var caught = require('caught');
var prm = caught(Promise.reject(new Error('fail')));

setTimeout(() => {
    prm.catch((err) => {
        console.log(err.message);
    })
}, 0);

免责声明:我是抓住了模块(是的,我是为这个答案写的)。

Disclaimer: I am the author of the caught module (and yes, I wrote it for this answer).

添加到节点在v6和v7之间中断更改 。在问题#830:默认的未处理拒绝检测行为中对此进行了激烈的讨论,没有关于异步附加拒绝处理程序的承诺应该如何表现的普遍协议 - 在没有警告的情况下工作,处理警告或者通过终止程序来禁止使用。有关 unhandled-rejections-spec 项目的几个问题进行了更多讨论。

It was added to Node as one of the Breaking changes between v6 and v7. There was a heated discussion about it in Issue #830: Default Unhandled Rejection Detection Behavior with no universal agreement on how promises with rejection handlers attached asynchronously should behave - work without warnings, work with warnings or be forbidden to use at all by terminating the program. More discussion took place in several issues of the unhandled-rejections-spec project.

此警告是为了帮助您找到忘记处理拒绝的情况,但有时您可能希望避免这种情况。例如,你可能想要制作一堆请求并将结果的promises存储在一个数组中,以便稍后在程序的其他部分处理它。

This warning is to help you find situations where you forgot to handle the rejection but sometimes you may want to avoid it. For example you may want to make a bunch of requests and store the resulting promises in an array, only to handle it later in some other part of your program.

其中一个承诺优于回调的优点是,您可以将创建承诺的位置与附加处理程序的位置(或位置)分开。这些警告使得操作变得更加困难,但您可以处理事件(我的第一个示例)或者在您创建不希望立即处理的承诺的任何地方附加虚拟捕获处理程序(第二个示例)。或者你可以为你做一个模块(第三个例子)。

One of the advantages of promises over callbacks is that you can separate the place where you create the promise from the place (or places) where you attach the handlers. Those warnings make it more difficult to do but you can either handle the events (my first example) or attach a dummy catch handler wherever you create a promise that you don't want to handle right away (second example). Or you can have a module do it for you (third example).

附加一个空如果你分两步执行,处理程序不会改变存储的promise的工作方式:

Attaching an empty handler doesn't change the way how the stored promise works in any way if you do it in two steps:

var prm1 = Promise.reject(new Error('fail'));
prm1.catch(() => {});

但这不一样:

var prm2 = Promise.reject(new Error('fail')).catch(() => {});

这里 prm2 将是一个不同的承诺然后 PRM1 。虽然 prm1 将因失败错误而被拒绝, prm2 将通过 undefined <解决/ code>这可能不是你想要的。

Here prm2 will be a different promise then prm1. While prm1 will be rejected with 'fail' error, prm2 will be resolved with undefined which is probably not what you want.

但是你可以写一个简单的函数让它像上面的两个例子一样工作,就像我使用抓住了模块:

But you could write a simple function to make it work like a two-step example above, like I did with the caught module:

var prm3 = caught(Promise.reject(new Error('fail')));

此处 prm3 与<$相同c $ c> prm1

请参阅: https://www.npmjs.com/package/caught

另请参阅请求#6375: lib,src:抛出未处理的承诺拒绝(2017年2月未合并)标记为 Milestone 8.0.0

See also Pull Request #6375: lib,src: "throw" on unhandled promise rejections (not merged yet as of Febryary 2017) that is marked as Milestone 8.0.0:


使承诺抛出拒绝退出,如常规未捕获错误 [强调添加]

这意味着我们可以期望Node 8.x更改此警告问题是关于崩溃并终止流程的错误,我们应该在今天编写程序时将其考虑在内以避免将来出现意外。

This means that we can expect Node 8.x to change the warning that this question is about into an error that crashes and terminates the process and we should take it into account while writing our programs today to avoid surprises in the future.

另请参阅 Node.js 8.0.0追踪问题#10117

这篇关于我应该避免异步处理Promise拒绝吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆