[软件设计/软件工程] 为什么在 Node.js 中使用异步等待时会丢失堆栈跟踪?

[复制链接]
发表于 2022-5-3 12:21:05
问题
当我运行以下程序时
  1. async function functionOne() {

  2.   throw new Error('Error here prints the complete stack');

  3.   await new Promise((resolve) => {
  4.     setTimeout(() => { resolve(); }, 1000);
  5.   });
  6. }

  7. async function functionTwo() {
  8.   await functionOne();
  9. }

  10. async function functionThree() {
  11.   await functionTwo();
  12. }

  13. functionThree()
  14.   .catch((error) => {
  15.     console.error(error);
  16.   });
复制代码

我得到以下输出,它通过各种调用函数打印堆栈
  1. Error: Error here prints the complete stack
  2.     at functionOne (/home/divyanshu/programming/errorHandlingAsyncAwait/index.js:3:9)
  3.     at functionTwo (/home/divyanshu/programming/errorHandlingAsyncAwait/index.js:11:9)
  4.     at functionThree (/home/divyanshu/programming/errorHandlingAsyncAwait/index.js:15:9)
  5.     at Object.<anonymous> (/home/divyanshu/programming/errorHandlingAsyncAwait/index.js:18:1)
  6.     at Module._compile (module.js:612:30)
  7.     at Object.Module._extensions..js (module.js:623:10)
  8.     at Module.load (module.js:531:32)
  9.     at tryModuleLoad (module.js:494:12)
  10.     at Function.Module._load (module.js:486:3)
  11.     at Function.Module.runMain (module.js:653:10)
复制代码

但是,当在以下程序中的等待调用后抛出错误时
  1. async function functionOne() {

  2.   await new Promise((resolve) => {
  3.     setTimeout(() => { resolve(); }, 1000);
  4.   });

  5.   throw new Error('Error here prints incomplete stack');

  6. }

  7. async function functionTwo() {
  8.   await functionOne();
  9. }

  10. async function functionThree() {
  11.   await functionTwo();
  12. }

  13. functionThree()
  14.   .catch((error) => {
  15.     console.error(error);
  16.   });
复制代码

这是输出
  1. Error: Error here prints incomplete stack
  2.     at functionOne (/home/divyanshu/programming/errorHandlingAsyncAwait/index.js:7:9)
  3.     at <anonymous>
复制代码

我想知道为什么堆栈跟踪在第二种情况下丢失了,但在第一种情况下没有。

回答
因为在第一个代码中,直到 Error 的所有内容都在事件循环的同一滴答声中。

在异步回调之前,来自 setTimeout 的调用堆栈可以进入调用堆栈(堆栈跟踪是从中构建的),调用堆栈必须为空。

因此,由于第一个代码在调用 Error 之前同步运行所有内容,因此所有这些调用都在调用堆栈上。但是在第二种方法中,在调用Error之后调用了await。当 setTimeout 完成时。事件循环将回调放回堆栈,为此,调用堆栈必须为空。

所以现在,没有 setTimeout &amp;amp;amp;代码>在调用堆栈上,所以它们不会出现。

堆栈跟踪是错误发生时堆栈的状态。

以下是这两个代码中堆栈的粗略解释:

第一个代码

功能二

第二个代码

功能三

我建议观看此视频以了解所有这些是如何工作的:

菲利普·罗伯茨到底是什么&amp;#39; “事件循环”
  1. 1) functionThree is pushed into the stack
  2. 2) functionTwo is pushed into the stack
  3. 3) functionOne is pushed into the stack
  4. 4) Error is thrown
复制代码

在最新版本的 Node.js 中,您可以使用





上一篇:如何用量角器测试数据采集器?
下一篇:如何使用 CSS 为容器中的特定单词着色

使用道具 举报

Archiver|手机版|小黑屋|吾爱开源 |网站地图

Copyright 2011 - 2012 Lnqq.NET.All Rights Reserved( ICP备案粤ICP备14042591号-1粤ICP14042591号 )

关于本站 - 版权申明 - 侵删联系 - Ln Studio! - 广告联系

本站资源来自互联网,仅供用户测试使用,相关版权归原作者所有

快速回复 返回顶部 返回列表