所以,我想運行一個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