所以,我想运行一个intervaled功能时,但有一个递归超时:避免堆栈溢出运行递归超时
var runUpdater = function() {
setTimeout(() => {
console.log('something here')
runUpdater()
}, 1000)
}
这将体现在将始终为长期服务运行时间。我认为这最终会出现堆栈溢出,对吗?我的问题是:避免它的最好方法是什么?
所以,我想运行一个intervaled功能时,但有一个递归超时:避免堆栈溢出运行递归超时
var runUpdater = function() {
setTimeout(() => {
console.log('something here')
runUpdater()
}, 1000)
}
这将体现在将始终为长期服务运行时间。我认为这最终会出现堆栈溢出,对吗?我的问题是:避免它的最好方法是什么?
不,不会有堆栈溢出。每次调用setTimeout
都会在事件循环中排队一条新消息。当执行setTimeout回调函数时,你会得到一个全新的堆栈,深度为1
,当执行线程完成时它将不再存在。例如,下面将迅速抛出达到最大堆栈大小时,引发RangeError:
try {
!function func () {
func();
}();
} catch (e) {
document.body.innerHTML = e.message;
}
但这个版本不会有任何问题无限期地运行:
try {
!function func () {
setTimeout(func, 0);
}();
} catch (e) {
document.body.innerHTML = e.message;
}
经过一些测试后,我认为您的当前代码没有递归。由于runUpdater()
在执行内部runUpdater()
后立即退出。 setTimeout()
调用并不会阻止浏览器的主线程,而是当浏览器空闲时安排您的函数调用,然后立即退出(随后终止调用者,因此不会发生递归)
我宁愿使用setInterval()
你的情况为可读性的原因,避免recursive
调用任何混乱:(!感谢)的基础上通过@Paulpro作出评论
setInterval(function() {
console.log('something here');
}, 1000);
编辑:
我认为setInterval
确实与相同与延迟和调用相同的功能,但它并没有,setTimeout的运行顺序,当你的函数调用runUpdater()
而setInterval
只是时间表忽略了功能的状态被称为
TL只安排下一次调用; DR:使用他的版本的答案
请注意,如果setInterval运行的代码比运行它(甚至是异步)之间的延迟时间更长,将会导致问题,因为它将继续排队越来越多的回调并进一步落后。如果每次都发出Ajax请求,那可能会非常糟糕。您可以很容易地达到您的浏览器一次发送的最大请求数,然后在其上建立一个大队列,并且如果您在别处发送任何其他Ajax请求,他们将不会长时间发送。 – Paulpro
@Paulpro指出,谢谢。 –
代码中没有递归 - >“问题”解决:) – Andreas
'setInterval()'怎么样? – ne1410s