2014-01-21 58 views
3

是否可以「無限期」運行此項,而不會導致堆棧溢出或內存不足?javascript中的遞歸setTimeout

function eternal(){ 
    var time = recalculateTime(); 
    doSomething(); 
    setTimeout(eternal,time); 
} 

setTimeout(eternal,200000); 

我沒有使用setInterval,因爲觸發時間是可變的。

+1

你的代碼應該可以正常工作,不會耗盡內存。你有麻煩嗎? –

+0

不,這是因爲在另一種語言(如C#或Java)中,類似這樣的事情最終會產生堆棧溢出異常,因爲它將是遞歸調用。 –

回答

5

這實際上並不是遞歸調用,因爲eternal()的第一次調用實際上在setTimeout()調用下一個調用之前完成。所以,這不是技術上的遞歸,並且不會隨着時間的推移建立堆棧。它可以在沒有任何積聚的情況下永久運行,這是保持反覆運行的完美方式。

爲了迴應您的某條評論,javascript不是多線程的,因此它不會爲定時器創建多個線程。觸發的每個定時器事件只是將事件放入事件隊列中,並且如果當時沒有JS正在運行,則觸發該事件(從而調用回調函數)。如果JS正在運行,那麼JS引擎會等待,直到當前正在執行的JS完成,然後爲事件隊列中的下一個事件提供服務(從而調用回調)。

1

這應該沒問題。一旦運行setTimeout,它將在eternal函數再次調用之前返回。

+0

它不會創建一個線程級聯,每個人都在等待他們的孩子完成?只是想知道,我不是很熟悉JavaScript的異步部分。 –

+1

正如我所提到的,jfriend00在他的回答中說,'eternal'方法在下次調用之前完成並返回。所以它實際上不是遞歸的。 –