gpt4 book ai didi

javascript - 使用 setTimeout 会阻止堆栈增长吗?

转载 作者:行者123 更新时间:2023-11-29 10:38:17 26 4
gpt4 key购买 nike

假设我正在对一组值进行某种长时间的操作。

启动这个操作的函数是startNext()

最后一行执行的是它自己,所以它是一个像这样的递归调用:

function startNext(){
var val = getNextValue()
workOnValue(val)
.then(doSomeMoreWork)
.then(doMoreStuff)
.then(moree)
.then(startNext);
}

这将使堆栈增长,因为尾递归在 JS 中不起作用(目前)。将最后一行更改为:

.then(function(){setTimeout(startNext, 0)});

工作更好?它不会填满堆栈,因为它向事件循环添加了一个新操作吗?

最佳答案

是的,setTimeout 将阻止堆栈增长,因为当前函数完成并且对自身的“递归”调用被放置在事件队列中。它还会运行得更慢,因为它不是直接调用而是通过队列处理。

为了演示和证明这一点,请尝试使用 Node 进行实验。

将下面的代码示例放入一个文件中,并将 simple 标志切换到底部。您会看到 recurseSimple 函数运行得非常快,并且很快就会炸毁堆栈。 recurseTimeout 运行速度较慢,但​​会一直运行。

function recurseSimple(count) {
// Count: 15269, error: bootstrap_node.js:392
// RangeError: Maximum call stack size exceeded
try {
if (count % 10000 === 0) {
console.log('Running count:', count);
}
recurseSimple(count + 1);
} catch (e) {
console.log(`Simple count: ${count}, error:`, e);
}
}

function recurseTimeout(count) {
// No stack exceeded
try {
if (count % 10000 === 0) {
console.log('Running count:', count);
}
setTimeout(recurseTimeout.bind(null, count + 1), 0);
} catch (e) {
console.log(`Timeout count: ${count}, error:`, e);
}
}

const simple = false;

if (simple) {
recurseSimple(0);
} else {
recurseTimeout(0);
}

完全相同的原则适用于 promise 。为了尽可能简单,我在这里没有使用 promises。

关于javascript - 使用 setTimeout 会阻止堆栈增长吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33310551/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com