使用setTimeout方法调用函数而不是直接调用函数,可以在javascript中避免堆栈溢出吗?我对setTimeout的理解是它应该启动一个新的callstack。当我查看chrome和IE的callstack时,似乎setTimeout调用正在等待函数调用返回。
这只是调试器的属性还是我的理解存在缺陷?
修改
虽然下面提供的答案是正确的,但我遇到的实际问题与我调用setTimeout(aFunction(),10)的事实有关,因为括号因此立即评估aFunction。 This question将我排除在外。
答案 0 :(得分:15)
我可以确认堆栈已清除。
考虑这种情况:
function a() {
b();
}
function b() {
c();
}
function c() {
debugger;
setTimeout( d, 1000 );
}
function d() {
debugger;
}
a();
因此有两个断点 - 一个位于函数c
的开头,另一个位于函数d
的开头。
在第一个断点处堆叠:
在第二个断点处堆叠:
答案 1 :(得分:5)
异步调用(例如来自setTimeout
的异步调用)确实会生成新的callstack。
当你说“当我查看chrome和IE的callstack时,看起来setTimeout调用正在等待函数调用返回时,你所描述的内容并不完全清楚。”但是,你可以做的一件事是在setTimeout
调用的函数中放置一个断点,并看到callstack是空的。
答案 2 :(得分:0)
还有另一种无需使用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)