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

问题描述:

我正在编写一个库。有一次,我创建了一个承诺,然后在稍后添加then/catch处理程序。在实际上将错误处理程序附加到它之前,承诺可能会失败。这对我来说很好;这个承诺可以存在于薛定谔猫般的状态中,直到我稍后可能决定去看它。防止触发全局'未处理拒绝'事件的承诺

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

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

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

有没有官方的方式可以标记一个承诺,将其排除在任何全球“未处理的拒绝”事件之外,还是我真的必须同步附加一个错误处理程序到每个承诺以避免这种情况?

+0

并非所有的环境都这样做,那些做的是错的恕我直言。只要你在某处提到承诺,环境就没有生意可言。 – jib

+1

没错,但我不能忽略现实,如果我想让我的库在Node中工作。除了实际情况之外,如果被拒绝的承诺没有被捕获,为避免难以捉摸的错误,应用程序想要大声退出是有正当理由的,所以必须有一种方式让图书馆作者从这个选项中退出其内部承诺 – callum

+1

不争论但在第二部分中,我认为Firefox做的是正确的事情:只有当它们不再被引用时,它才会对被拒绝的未承诺的承诺大声疾呼。这唯一的缺点是,这个报告目前需要几秒钟(可能与垃圾回收超时),但我相信他们正在处理它。 – jib

在环境(节点)上记录一个错误。环境中没有任何业务可以通过脚本观察到。

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

即使Chrome会初始将其标记为控制台中的“未处理的承诺拒绝”,并带有✖符号并将其称为错误,但如果随后处理承诺,则会将其退回,并将changing更改为✓ ,并将其语言改为“1处理承诺拒绝”。

只有在未处理的承诺拒绝被垃圾收集时,Firefox才会投诉。

一种解决方法可能是添加一个hold功能,是这样的:

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>

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

然后使用它时,你知道你会得到一个承诺后沉默节点