Javascript 在运行递归超时时避免堆栈溢出

Javascript 在运行递归超时时避免堆栈溢出,javascript,node.js,Javascript,Node.js,因此,我想运行一个intervaled函数,但需要递归超时: var runUpdater = function () { setTimeout(() => { console.log('something here') runUpdater() }, 1000) } 这将在一个服务上运行,该服务将一直运行很长一段时间。我想这最终会导致堆栈溢出,对吗?我的问题是:避免它的最佳方法是什么?经过一点测试,我认为您当前的代码没有递归。AsrunUpdater()在执行内

因此,我想运行一个intervaled函数,但需要递归超时:

var runUpdater = function () {
  setTimeout(() => {
    console.log('something here')
    runUpdater()
  }, 1000)
}

这将在一个服务上运行,该服务将一直运行很长一段时间。我想这最终会导致堆栈溢出,对吗?我的问题是:避免它的最佳方法是什么?

经过一点测试,我认为您当前的代码没有递归。As
runUpdater()
在执行内部
runUpdater()
后立即退出
setTimeout()
call不会阻塞浏览器的主线程,而是在浏览器空闲时安排函数调用,然后立即退出(这会终止调用程序,因此不会发生递归)

为了可读性,我更愿意在您的情况下使用
setInterval()
,并避免对
recursive
调用的任何混淆:

setInterval(function() {
    console.log('something here');
}, 1000);
根据@Paulpro的评论进行编辑(谢谢!):

我假设
setInterval
setTimeout
延迟和调用同一个函数也有同样的作用,但事实并非如此,setTimeout是按顺序运行的,只在函数调用
runUpdater()
时安排下一次调用,而
setInterval
只安排忽略被调用函数的状态


tl;dr:使用他的答案版本

不,不会出现堆栈溢出。每次调用
setTimeout
都会在事件循环中对新消息进行排队。当执行对setTimeout的回调时,将有一个深度为
1
的全新堆栈,当执行线程完成时,该堆栈将不再存在。例如,当达到最大堆栈大小时,以下命令将快速抛出RangeError:

试试看{
!函数func(){
func();
}();
}捕获(e){
document.body.innerHTML=e.message;

}
代码中没有递归->“问题”已解决:)关于
setInterval()
?请注意,如果正在运行的代码所花费的时间超过运行它之间的延迟(甚至异步),setInterval将导致问题,因为它将继续排队等待越来越多的回调,并越来越落后。如果每次都发出Ajax请求之类的话,情况会变得非常糟糕。您可以轻松地达到浏览器一次发送的最大请求数,然后在此基础上建立一个大型队列,如果您在其他地方发出任何其他Ajax请求,它们将在很长时间内不会被发送。