防止承诺触发全局“未处理的拒绝”事件

Prevent a promise from triggering a global 'unhandled rejection' event

本文关键字:未处理 拒绝 事件 全局 承诺      更新时间:2023-09-26

我正在编写一个库。在某一时刻,我创建了一个承诺,然后突然加入以向其添加then/catch处理程序。在我实际附加错误处理程序之前,承诺可能会失败。这对我来说很好;这个承诺可以以薛定谔猫般的状态存在,直到我后来可能决定看看它。

问题是,如果任何承诺在没有错误处理程序的情况下被拒绝,某些环境会触发全局事件。也许我的一个用户在 Node 中做了这样的事情:

process.on('unhandledRejection', function(reason){
    console.error('oops', reason);
    process.exit(1);
});

不希望我被拒绝的承诺触发它,如果我知道我稍后会去检查它的结果。

是否有某种官方方法可以标记承诺以将其从任何全局"未处理的拒绝"事件中排除,或者我是否真的必须将错误处理程序同步附加到每个承诺以避免这种情况?

在环境(节点)上提交错误。环境没有业务以脚本可观察到的方式对其执行操作。

在Firefox和Chrome中,AFAIK没有脚本可观察到的后果。

尽管 Chrome 最初会在控制台✖中将其标记为"未处理的承诺拒绝",并带有一个符号,并称其为错误,但如果随后处理承诺,它会稍后退缩,将 ✓ 更改为 ✖ ✓,并将其语言更改为"1 个处理的承诺拒绝"。

Firefox 只会在垃圾回收未处理的承诺拒绝时进行投诉。

解决方法可能是添加hold函数,如下所示:

var hold = p => (p.catch(() => {}), p);

然后使用它来使 Node 静音,只要你知道你以后会得到一个承诺:

var console = { log: msg => div.innerHTML += msg + "<br>" };
window.onerror = () => console.log("window onerror fired");
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var hold = p => (p.catch(() => {}), p);
var p = hold(Promise.reject(new Error("failure")));
wait(2000).then(() => p).catch(e => console.log(e.message + " handled."));
<div id="div"></div>