调用setTimeout是否清除调用栈?

Does calling setTimeout clear the callstack?

本文关键字:调用 是否 setTimeout 清除      更新时间:2023-09-26

可以通过使用setTimeout方法调用函数而不是直接调用它来避免javascript中的堆栈溢出吗?我对setTimeout的理解是,它应该启动一个新的调用栈。当我在chrome和IE的调用堆栈中查看时,似乎setTimeout调用正在等待函数调用返回。

这只是调试器的属性还是我的理解有缺陷?

编辑

虽然下面提供的答案是正确的,但我遇到的实际问题与我正在调用setTimeout(function(), 10)这一事实有关,因为括号立即对function进行评估。

我可以确认堆栈已被清除。

考虑这个场景:

function a() {
     b();   
}
function b() {
     c();   
}
function c() {
    debugger;
    setTimeout( d, 1000 );
}
function d() {
    debugger;
}
a();

所以有两个断点,一个在函数c的开始,一个在函数d的开始。

第一个断点处的栈:

  • c ()
  • b ()
  • ()

第二个断点处的栈:

  • d ()

现场演示: http://jsfiddle.net/nbf4n/1/

异步调用,例如来自setTimeout的调用,确实会生成一个新的调用堆栈。

当你说"当我在chrome和IE的调用堆栈中查看时,似乎setTimeout调用正在等待函数调用返回"时,你所描述的并不完全清楚。但是,您可以做的一件事是在setTimeout调用的函数中放置一个断点,并看到调用堆栈为空。

还有另一种不使用setTimeout()的方法来清除调用堆栈:

testLoop.js

let counter = 0;
const max = 1000000000n  // 'n' signifies BigInteger
Error.stackTraceLimit = 100;
const A = () => {
  fp = B;
}
const B = () => {
  fp = A;
}
let fp = B;
const then = process.hrtime.bigint();
loop:   // label is not needed for this simple case though useful for some cases
for(;;) {
  counter++;
  if (counter > max) {
    const now = process.hrtime.bigint();
    const nanos = now - then;
    console.log({ "runtime(sec)": Number(nanos) / (1000000000.0) })
    throw Error('exit')
  }
  fp()
  continue loop;
}
输出:

$ node testLoop.js
{ 'runtime(sec)': 20.647399601 }
C:'Users'jlowe'Documents'Projects'clearStack'testLoop.js:25
    throw Error('exit')
    ^
Error: exit
    at Object.<anonymous> (C:'Users'jlowe'Documents'Projects'clearStack'testLoop.js:25:11)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)