如何调试 javascript 承诺?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25827234/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to debug javascript promises?
提问by YemSalat
I am trying to understand how to debug asynchronous code that is based on promises. By Promises I mean ECMAScript 6 based promises and by debugging I mean using the built-in chrome or firefox debugger.
我试图了解如何调试基于承诺的异步代码。我所说的承诺是指基于 ECMAScript 6 的承诺,而我所说的调试是指使用内置的 chrome 或 firefox 调试器。
What I am having trouble with - is that when an error occurs I can't seem to get the stack trace no matter how I 'reject' it.
我遇到的问题是 - 发生错误时,无论我如何“拒绝”它,我似乎都无法获得堆栈跟踪。
I tried these:
我试过这些:
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'));
But none of those returns the actual error in the code, or the stack trace.
但是这些都没有返回代码中的实际错误或堆栈跟踪。
So my question is - how to properly debug javascript Promises?
所以我的问题是 - 如何正确调试 javascript Promises?
采纳答案by Benjamin Gruenbaum
This is a great topic to discuss, the sad news are this is actually quite hard with native promises.
这是一个值得讨论的好话题,可悲的消息是,对于原生 Promise 来说,这实际上很难。
Debugging raw ES6 promises in Chrome is horrible. This is because they will silently suppress errors and whenever you omit a catch it will not give you any indication that the promise failed.Update: Chrome now logs unhandled rejections (see this link for how)
在 Chrome 中调试原始 ES6 承诺是可怕的。这是因为它们会默默地抑制错误,并且无论何时您省略捕获,它都不会给您任何承诺失败的迹象。更新:Chrome 现在会记录未处理的拒绝(有关方法,请参阅此链接)
Promise.resolve("foo").then(function(){
throw new Error("You will never see this");// silent failure
});
In Firefox, things are a bit better since they perform unhandled rejection detection - however, it's still flakey and if you assigned the promise anywhere it won't work.
在 Firefox 中,情况会好一些,因为它们执行未处理的拒绝检测 - 但是,它仍然是不稳定的,如果您将承诺分配到任何地方,它都将不起作用。
So, what can be done?
那么,有什么办法呢?
Include Bluebird- it's a superset of ES6 promises and you can swap it right inside, it has a richer API, it's faster and it has amazing stack traces. It's built with debugging in mind and includes great error handling facilities.
包括Bluebird- 它是 ES6 promises 的超集,你可以直接在里面交换它,它有一个更丰富的 API,它更快,它有惊人的堆栈跟踪。它在构建时考虑到了调试,并包括出色的错误处理设施。
Once you've included Bluebird, call:
包含 Bluebird 后,请致电:
Promise.longStackTraces();
Which will slow it down a bit (it'll still be very fast) and will give you amazing error messages. For example:
这会减慢它的速度(它仍然会非常快)并且会给你惊人的错误信息。例如:
Promise.resolve().then(function outer() {
return Promise.resolve().then(function inner() {
return Promise.resolve().then(function evenMoreInner() {
a.b.c.d()
});
});
});
In native promises - this will be a silent failure and will be very hard to debug - with Bluebird promises this will show a big red error in your console by default giving you:
在本机承诺中 - 这将是一个无声的失败并且很难调试 - 使用 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)
Once you're done debugging - you can swap it out and go back to native promises. Personally I value knowing I have errors in production so I don't recommend it but it's certainly doable.
完成调试后 - 您可以将其换出并返回到本机承诺。我个人很重视知道我在生产中存在错误,所以我不推荐它,但它肯定是可行的。
回答by goat
*This doesn't directly answer your question, but it may be helpful nonetheless.
*这并不能直接回答您的问题,但可能会有所帮助。
Chrome devtools recently got a new feature that's useful for debugging async code, such as Promises.
Chrome devtools 最近获得了一项新功能,可用于调试异步代码,例如 Promises。
http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/
http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/
Basically, enable the "async" checkbox in the sources tab, and Chrome will reconstruct the call stack for you as if it were synchronous code.
基本上,启用源选项卡中的“异步”复选框,Chrome 将为您重建调用堆栈,就好像它是同步代码一样。
回答by Matthias M
This answer is an addition to Benjamin Gruenbaum's answer: If you use a catch statement in the promise chain, you'll get the stack trace by error.stack:
这个答案是对 Benjamin Gruenbaum 答案的补充:如果您在承诺链中使用 catch 语句,您将通过error.stack获得堆栈跟踪:
Promise.longStackTraces();
function outer() {
return Promise.resolve();
}
function inner() {
return Promise.resolve();
}
function evenMoreInner() {
a.b.c.d()
}
Promise.resolve()
.then(outer)
.then(inner)
.then(evenMoreInner())
.catch(function (err) {
console.log(err.message);
console.log(err.stack);
});
Error Message:
错误信息:
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)
回答by Johan Bergens
They seem to be working with debug tools in Chrome. See this thread for more info.
他们似乎正在使用 Chrome 中的调试工具。有关更多信息,请参阅此线程。
https://code.google.com/p/v8/issues/detail?id=3093
https://code.google.com/p/v8/issues/detail?id=3093
I havn't checked if this is already in the dev version or beta version but I hope it will be soon. It might then be included in the normal version in January 2015 or so (just a personal guess, absolutley no promise since I don't even work for Google).
我还没有检查这是否已经在开发版或测试版中,但我希望它很快就会出现。然后它可能会在 2015 年 1 月左右包含在普通版本中(只是个人猜测,绝对没有承诺,因为我什至不为 Google 工作)。
回答by ra9r
The best way to debug promised is to listen to unhandledRejectionevent of your process.
调试承诺的最佳方法是侦听unhandledRejection您的process.
For example, here is how you might set it up and dump a stack trace...
例如,这里是您如何设置它并转储堆栈跟踪...
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// Stack Trace
console.log(reason.stack);
});
回答by jmojico
You can add a console.log() statement in the .then() function of the Promise object: You can also add in the .catch() if needed.
您可以在 Promise 对象的 .then() 函数中添加 console.log() 语句:如果需要,您还可以添加 .catch() 。
genericDbCaller(dbName, collectionName, dbFunctionName, params) {
return new Promise((resolve, reject) => {
DatabaseContext.instance.getDbConn(dbName)
.then((dbConn) => {
dbConn.get(collectionName)[dbFunctionName].apply(null, params)
.then(
(docs) =>{
----->>> console.log(docs);
resolve(docs);
})
.catch((e)=>{


