在vscode中调试Promise调用堆栈

BrD*_*aHa 10 javascript node.js es6-promise visual-studio-code

在vscode中调试nodeJS Promises时有没有办法获取调用堆栈?我看到这个GitHub问题支持异步调用堆栈,但看起来它与vanilla JS回调有关.

现在,当我在断点处暂停时,调用堆栈很小,即使我知道这个函数是从另一个(几个)函数调用的.

我在节点v6.9.x上运行

debug break没有堆栈

编辑:将"protocol": "inspector"属性添加到launch.json配置添加更多的堆栈帧,但它不是很有帮助:debug break next tick

我的所有函数都返回promises,屏幕截图中的函数被称为调用中的一个函数Promise.all().

Jon*_*lms 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
}
Run Code Online (Sandbox Code Playgroud)

在上面的点上,当第一个.then回调 (1) 执行时,唯一附加的回调是 (2),因此引擎可以生成一个“异步堆栈跟踪”,显示 Promise 链在哪些函数处继续。

现在,对于简单的 Promise 来说,解析这些链只是为了生成堆栈跟踪会产生大量开销,但是对于Promisesasync function来说,await这非常简单。因此,从 NodeJS v12 开始(以及在现代浏览器中),如果您像这样编写上面的内容:

function a() {
   return Promise.resolve(1).then(it => it + 1); // 1
}

function b() {
   return a().then(it => it + 1); // 2
}
Run Code Online (Sandbox Code Playgroud)

然后您的调试器将显示正确的异步堆栈跟踪(如上所述生成)。您可以在这里找到更深入的解释。