这是一个值得讨论的好话题,可悲的是,对于原生承诺来说,这实际上是相当困难的。
在 Chrome 中调试原始 ES6 承诺是可怕的。这是因为它们会默默地抑制错误,并且无论何时你省略了一个 catch,它都不会给你任何承诺失败的迹象。更新:Chrome 现在记录未处理的拒绝(请参阅此链接了解如何)
Promise.resolve("foo").then(function(){
throw new Error("You will never see this");// silent failure
});
在 Firefox 中,情况要好一些,因为它们执行未处理的拒绝检测 - 但是,它仍然很不稳定,如果你将承诺分配到任何地方,它就不会起作用。
那么,可以做些什么呢?
包括Bluebird——它是 ES6 Promise 的超集,你可以直接在里面交换它,它有更丰富的 API,速度更快,并且有惊人的堆栈跟踪。它在构建时考虑到了调试,并包括出色的错误处理工具。
包含 Bluebird 后,请致电:
Promise.longStackTraces();
这会减慢它的速度(它仍然会非常快)并且会给你惊人的错误信息。例如:
Promise.resolve().then(function outer() {
return Promise.resolve().then(function inner() {
return Promise.resolve().then(function evenMoreInner() {
a.b.c.d()
});
});
});
在本机承诺中 - 这将是一个静默失败,并且很难调试 - 使用 Bluebird 承诺,默认情况下这将在您的控制台中显示一个大的红色错误,为您提供:
ReferenceError: a is not defined
at evenMoreInner (<anonymous>:6:13)
From previous event:
at inner (<anonymous>:5:24)
From previous event:
at outer (<anonymous>:4:20)
From previous event:
at <anonymous>:3:9
at Object.InjectedScript._evaluateOn (<anonymous>:581:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:540:52)
at Object.InjectedScript.evaluate (<anonymous>:459:21)
完成调试后 - 您可以将其换掉并返回到原生 Promise。就我个人而言,我很重视知道我在生产中有错误,所以我不推荐它,但它肯定是可行的。