如何debuggingJavaScript的承诺?

我想了解如何debugging基于promise的asynchronous代码。 承诺我的意思是基于ECMAScript 6的承诺,通过debugging我的意思是使用内置的铬或Firefoxdebugging器。

我遇到的麻烦是,当出现错误时,无论如何“拒绝”,我都无法得到堆栈跟踪。

我试过这些:

console.log(new Error('Error occured')); throw new Error('Throwing an Error'); return new Error('Error returned by the onRejected function'); reject(new Error('Pass Error to the reject function')); 

但是,这些都不会返回代码中的实际错误或堆栈跟踪。

所以我的问题是 – 如何正确debuggingJavaScript承诺?

这是一个很好的话题,可悲的消息是,对于土着承诺来说,这实际上是相当困难的。

在Chrome中debugging原始的ES6承诺是可怕的。 这是因为他们会默默地压制错误,只要你忽略了一个错误,它就不会给你任何迹象表明这个承诺失败了。 更新:Chrome现在logging未处理的拒绝(请参阅此链接了解如何)

  Promise.resolve("foo").then(function(){ throw new Error("You will never see this");// silent failure }); 

在Firefox中,因为执行了未处理的拒绝检测,所以情况会好一些 – 但是,它仍然是一片混乱,如果您在任何地方分配了这个承诺,它将无法工作。

那么,可以做些什么呢?

包括Bluebird – 它是ES6承诺的超集,你可以在里面交换它​​,它有一个更丰富的API,它更快,它有惊人的堆栈跟踪 。 它是在debugging的基础上构build的,包含了很好的error handlingfunction。

一旦你包括蓝鸟,请致电:

 Promise.longStackTraces(); 

这会减慢它(它将仍然是非常快),并会给你惊人的错误信息。 例如:

 Promise.resolve().then(function outer() { return Promise.resolve().then(function inner() { return Promise.resolve().then(function evenMoreInner() { abcd() }); }); }); 

在原生承诺中 – 这将是一个沉默的失败,将是非常难以debugging – 与蓝鸟承诺这将显示在您的控制台默认情况下给你一个大红色的错误:

 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) 

一旦你完成debugging – 你可以交换出来,回到本地的承诺。 我个人认为我知道我在生产中有错误,所以我不推荐它,但它肯定是可行的。

*这不直接回答你的问题,但它可能是有帮助的。

Chrome devtools最近得到了一个新的function,可以用来debuggingasynchronous代码,比如Promises。

http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/

基本上,启用来源选项卡中的“asynchronous”checkbox,Chrome将为您重新构build调用堆栈,就像它是同步代码一样。

截图

这个答案是对Benjamin Gruenbaum的回答的一个补充:如果你在promise链中使用catch语句,你将得到error.stack的堆栈跟踪:

  Promise.longStackTraces(); function outer() { return Promise.resolve(); } function inner() { return Promise.resolve(); } function evenMoreInner() { abcd() } Promise.resolve() .then(outer) .then(inner) .then(evenMoreInner()) .catch(function (err) { console.log(err.message); console.log(err.stack); }); 

错误信息:

 ReferenceError: a is not defined at evenMoreInner (test/test_promise.js:58:17) <<<< HERE's the error! at Context.<anonymous> (test/test_promise.js:64:23) 

他们似乎正在使用Chrome中的debugging工具。 看到这个线程的更多信息。

https://code.google.com/p/v8/issues/detail?id=3093

我没有检查,如果这已经在开发版或testing版,但我希望它会很快。 它可能会包含在2015年1月份的正常版本中(只是个人猜测,绝对没有承诺,因为我甚至没有为Google工作)。