使用 .done() 时如何捕获 Bluebird 中未处理的拒绝?

How to catch unhandled rejections in Bluebird when using .done()?

通常,当发生未处理的拒绝时,Bluebird 会像这样调度 unhandledrejection 事件:

// The message is logged, great!
window.addEventListener("unhandledrejection", function(e) {
    console.log("got unhandled rejection")
});
Promise.reject(new Error())

但是,一旦我将承诺链显式标记为 .done(),就不再调度事件:

// The message is not logged, boo!
window.addEventListener("unhandledrejection", function(e) {
    console.log("got unhandled rejection")
});
Promise.reject(new Error()).done()

请不要粘贴样板答案"bluebird is smart enough to handle .done() for you"。我想特别询问在使用 .done() 时如何处理未捕获的拒绝。特别是我需要这个,因为 unhandledrejection 在适当的时候被触发 .catch 是异步附加的,在我的例子中就是这样。

在 Q 中,它按预期工作(尽管 Q 实际上 要求 您使用 .done() 完成承诺链):

Q.onerror = function() {
    console.log("got unhandled rejection")
};
Q.reject(new Error()).done();

当您调用 done 时,您明确要求 Bluebird 将拒绝转换为抛出的异常。

您可以使用 window.onerror(或对应的 addEventListener)捕获所有这些。

window.onerror = function(e){
     // done makes it into a thrown exception - so catch it here.
};

P.S.

人们 post "bluebird is clever enough" 样板的原因主要是因为它是正确的(从 1.3 开始 Q 也是如此)。出于多种原因,在任何地方使用 .done 都容易出错且存在问题。本机承诺也不支持它。