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

Javascript 防止承诺触发全局';未经处理的拒绝';事件,javascript,promise,Javascript,Promise,我在写图书馆。在某一点上,我创建了一个承诺,然后在稍后加入then/catch处理程序。在我实际附加错误处理程序之前,承诺可能会失败。这对我很好;这个承诺可以存在于薛定谔猫的状态中,直到我后来决定去看它 问题是,如果任何承诺在没有错误处理程序的情况下被拒绝,某些环境会触发全局事件。也许我的一个用户在Node中做了一些极端的事情: 我不希望我被拒绝的承诺触发这种情况,如果我知道我以后会去检查结果的话 是否有某种官方方法可以标记一个承诺,将其从任何全局“未处理拒绝”事件中排除,或者我真的必须为每个承

我在写图书馆。在某一点上,我创建了一个承诺,然后在稍后加入
then/catch
处理程序。在我实际附加错误处理程序之前,承诺可能会失败。这对我很好;这个承诺可以存在于薛定谔猫的状态中,直到我后来决定去看它

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

我不希望我被拒绝的承诺触发这种情况,如果我知道我以后会去检查结果的话


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

在环境(节点)上归档一个bug。环境不应该以脚本可以观察到的方式对其进行操作

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

尽管Chrome最初会在控制台中将此标记为“未处理的承诺拒绝”,但会使用✖ 符号,并将其称为错误,如果承诺随后得到处理,则它会在以后回退,从而更改✖ 到✓, 并将其语言改为“拒绝承诺”

Firefox只会在未经处理的拒绝承诺被垃圾收集的情况下进行投诉

解决方法可能是添加一个
hold
函数,类似于:

var hold = p => (p.catch(() => {}), p);
然后,当您知道以后会得到承诺时,使用它使节点静音:

var控制台={log:msg=>div.innerHTML+=msg+”
“}; window.onerror=()=>console.log(“window-onerror已触发”); var wait=ms=>newpromise(resolve=>setTimeout(resolve,ms)); var hold=p=>(p.catch(()=>{}),p); var p=持有(承诺、拒绝(新错误(“失败”)); wait(2000).then(()=>p).catch(e=>console.log(e.message+“handled”)
并非所有环境都这样做,而且这样做的环境是错误的。只要你在某个地方引用了承诺,环境就没有必要大发雷霆。没错,但如果我想让我的库在Node中工作,我不能忽视现实。撇开现实不谈,如果一个被拒绝的承诺没有实现,应用程序想要大声退出是有正当理由的,以避免难以捉摸的bug,因此图书馆作者必须有一种方法从中选择他们的内部承诺不与现实争辩,然而在第二部分,我相信Firefox做了正确的事情:只有当承诺不再被引用时,它才会大喊大叫。唯一的缺点是,这个报告目前需要几秒钟的时间(可能是垃圾收集超时),但我相信他们正在努力。啊,这听起来确实是一个很好的方法。虽然从技术上讲,它会错过一些承诺仍在某个范围内的情况,但是由于代码中的一些错误,您无法添加catch处理程序。在这种情况下,您会遇到“uncaughtRejection”事件要解决的错误吞咽问题。无论如何,节点行为的现实,即使他们在未来的版本中改变了它,也意味着库作者必须假设一个未经许可的拒绝可能会使某人的应用程序崩溃,不管我们是否认为这是一件好事。因此,我想我们必须努力解决这个问题,永远不要让一个滴答声以一个未经处理的承诺结束。
hold
这个想法太棒了!超级简单,实现我们在这里想要的。酷!
var hold = p => (p.catch(() => {}), p);