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

时间:2016-01-09 18:05:57

标签: javascript node.js

所以,我想运行一个intervaled函数,但是有一个递归超时:

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

这将在一项长时间持续开启的服务上运行。我假设这最终会出现堆栈溢出,我是对的吗?我的问题是:避免它的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

经过一些测试后,我认为您当前的代码没有递归。由于runUpdater()在执行内部runUpdater()后立即退出。 setTimeout()调用不会阻止浏览器的主线程,而是它会在您的浏览器空闲时调度函数调用,然后立即退出(随后终止调用者,因此不会发生递归)

我希望在您的情况下使用setInterval()是为了便于阅读并避免混淆recursive次来电:

setInterval(function() {
    console.log('something here');
}, 1000);

根据@Paulpro的评论进行编辑(谢谢!):

我假设setIntervalsetTimeout执行相同的延迟并调用相同的函数,但它没有,setTimeout按顺序运行,只在您的函数调用时调度下一个调用{{1而runUpdater()只是调度忽略被调用函数的状态

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

答案 1 :(得分:1)

不,不会有堆栈溢出。每次调用1都会在事件循环中对新消息进行排队。当执行setTimeout的回调时,你有一个深度为try { !function func ( ) { func(); }(); } catch ( e ) { document.body.innerHTML = e.message; }的全新堆栈,当执行线程完成时它将不复存在。例如,当达到最大堆栈大小时,以下内容将快速抛出RangeError:

try {
    !function func ( ) {
        setTimeout( func, 0 );
    }();
} catch ( e ) {
    document.body.innerHTML = e.message;
}

但是这个版本将无限期地运行而没有问题:

Select(driver.findElement(By.id("BirthMonth"))).selectByVisibleText("February");