Nodejs - 从异步调用获取堆栈跟踪

问题描述 投票:0回答:1

我有以下简化代码:

async function fun() {
  function fun1() {
    return Promise.resolve(
      new Promise((resolve, reject) => {
        resolve();
      }),
    );
  }

  function fun0() {
    return fun1().then((_) => {
      return new Promise((resolve, reject) => {
        console.log(new Error().stack);
      });
    });
  }

  fun0();
}

(async () => {
  await fun();
})();

我的目标是获得完整的调用堆栈。但是,上面的输出仅包含匿名 Promise 的位置,而不包含

fun0
fun1

有没有办法在 v8 中获取整个堆栈跟踪?

node.js v8
1个回答
0
投票

您的问题有点误导,因为您所看到的实际上是当前堆栈 - 一旦触发异步操作(在您的情况下通过调用

resolve()
安排 Promise 的结算)同步执行将继续,堆栈将展开直到它最终是空的。然后,在某个时刻,异步事件被推入任务队列并最终被拾取,调用 Promise 中存储的 then-handler。因此,您看到的实际上是堆栈(如 - V8 调试器根据执行的内部表示将其重建为逻辑堆栈)。


也就是说,V8 实际上可以跟踪和“异步堆栈”——这意味着每当异步事件发生时,它都会存储当前堆栈(作为某种字符串)并将其附加到异步事件。然后,当事件完成并且任务被拾取时,它将存储的堆栈和异步堆栈缝合在一起 - 有关更多详细信息,请参阅此相关问题。由于这会带来相当大的开销,因此仅当在 Chrome 中打开调试器时才会存储堆栈 - 我想可以通过将调试器附加到正在运行的 NodeJS 进程来触发相同的操作。

© www.soinside.com 2019 - 2024. All rights reserved.