在给定的函数

async function x(n) {
    console.log(n);
    console.trace();
    if (n >= 3) { return; };
    await setTimeout(() => x(n+1), 1000);
}

x(0);

我可以看到控制台中的痕迹越来越长.

将其与递归版本进行比较,

async function x(n) {
    console.log(n);
    console.trace();
    if (n >= 3) { return; };
    x(n+1);
}

x(0);

你可以看到痕迹也在增长.那么,setTimeout是否也在增加堆栈,或者这种增长跟踪背后的解释是什么?

推荐答案

不,在setTimeout版本中堆栈不会增长.您在console.trace()的输出中看到的内容在the MDN docs中描述如下:

注意:在某些浏览器中,console.trace()可能还会输出指向不在调用堆栈上的当前console.trace()的调用和异步事件序列,以帮助识别当前事件求值循环的来源.

您至少可以在基于Chromium的浏览器中看到这一点,如果您不使用console.trace(),而是获得当前的实际堆栈:

async function x(n) {
  console.log(n);
  console.log(new Error().stack);
  if (n >= 3) {
    return;
  };
  await setTimeout(() => x(n + 1), 1000);
}

x(0);

在其他浏览器中,这一结果可能会有所不同,因为.stack是一个非标准属性,但至少在Chromium中,它显示了从JavaScript事件循环触发的当前实际堆栈.

Javascript相关问答推荐

我可以后增量超过1(最好是内联)吗?

如何解决(不忽略)reaction详尽的linter规则,而不会在获取数据时导致无限的reender循环

从外部访问组件变量-Vueejs

Flisk和JS错误:未捕获的Syntax错误:意外的令牌'<'

为什么我的列表直到下一次提交才更新值/onChange

你怎么看啦啦队的回应?

JS—删除对象数组中对象的子对象

如何使用子字符串在数组中搜索重复项

Chart.js-显示值应该在其中的引用区域

为什么我的getAsFile()方法返回空?

如何在.NET Core中将chtml文件链接到Java脚本文件?

如何在 Select 文本时停止Click事件?

面对代码中的错误作为前端与后端的集成

每次重新呈现时调用useState initialValue函数

如何使用<;Link>;执行与JS Reaction中的";window.Location=/GameOverDied;";类似的操作?

如何使用画布在另一个内部绘制一个较小但相同的形状,同时保持恒定的边界厚度?

React:防止useContext重新渲染整个应用程序或在组件之间共享数据而不重新渲染所有组件

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

ReferenceError:无法在初始化之前访问setData

使用createBrowserRoutVS BrowserRouter的Reaction路由