在vscode中调试nodeJS Promises时有没有办法获取调用堆栈?我看到this GitHub issue支持异步调用堆栈,但看起来它与vanilla JS回调有关。
现在,当我在断点处暂停时,调用堆栈很小,即使我知道这个函数是从另一个(几个)函数调用的。
我在节点v6.9.x上运行
编辑:将using
属性添加到launch.json配置会添加更多堆栈框架,但它不是很有帮助:
我的所有函数都返回promises,屏幕截图中的函数被称为"protocol": "inspector"
调用中的函数之一。
答案 0 :(得分:2)
首先,如图所示的调用堆栈是正确的,因为这些是实际在堆栈上的函数。当围绕异步回调创建 Promise 并附加 .then
处理程序时,同步执行结束并且调用堆栈被解包。当回调在某个时间回调时,它会解析 Promise 并执行 .then
处理程序。此时,调用堆栈仅包含传递给 .then
的函数。
现在在很多情况下,Promise 链是扁平的,并且与创建时相反:
function a() {
return Promise.resolve(1).then(it => it + 1); // 1
}
function b() {
return a().then(it => it + 1); // 2
}
在上面第一个 .then
回调 (1) 执行时,唯一附加的回调是 (2),因此引擎可以生成“异步堆栈跟踪”,显示 Promise 链在哪些函数处继续。
现在对于普通的 Promise 来说,解析这些链只是为了生成一个堆栈跟踪是很多开销,但是对于 async function
的 await
Promise 来说,它非常简单。因此,从 NodeJS v12(以及现代浏览器)开始,如果你像这样编写上面的代码:
async function a() {
const result = (await 1);
_log_stack();
return result + 1;
}
async function b() {
return (await a()) + 1;
}
b();
function _log_stack() { console.log((new Error()).stack); }
然后您的调试器将显示正确的异步堆栈跟踪(如上所述生成)。您可以找到更深入的解释 here。