2013-03-01 65 views
2

感謝您的期待。如何在不溢出堆棧的情況下在JavaScript中編寫遞歸阻塞函數?

背景

我寫了一個客戶端一個JavaScript重應用程序,有需要的實用功能,我可以通過一個條件和一個回調函數。如果條件不滿足,我需要等待幾毫秒,然後再次測試。如果條件滿足,則執行回撥。

我至今

我寫了這個方法,一個工具類的一部分:

ThreadLocker: function (condition, callback) { 
     //If condition is true then it resumes running code 
     if (condition()) { 
      callback(); 
     } else { //Else it waits 10ms and tries again 
      setTimeout(Util.ThreadLocker(condition,callback), 10); 
     } 
    } 

這裏是如何使用它:

var condition = function(){return (myGlobalVariable == "foo") ? true : false;}; 
    var callback = function(){alert("Ready to rock!");}; 

    Util.Threadlocker(condition,callback); 

問題

即使我將超時期限設置爲10 ,我立即發生堆棧溢出。以下是Chrome給我的內容:

「超出最大調用堆棧大小」。

如果你看看堆棧,它看起來像在幾秒或幾秒內調用了幾十次,即使setTimeOut被設置爲10秒也是如此。

我在這裏做錯了什麼?

回答

3

setTimeout(Util.ThreadLocker(condition,callback), 10); 

直接調用你的 '螺紋鎖' 功能,沒有超時設置。嘗試

setTimeout(function() { Util.ThreadLocker(condition,callback); }, 10); 

您可能還需要知道,即javaScript不是多線程的。它只是在n ms之後調用你的函數,或者一旦沒有其他任何東西被執行。如果創建間隔爲10毫秒,則間隔相同:任務需要30毫秒,它會在第10毫秒內執行,然後在第40秒從開始(第一個任務完成後立即執行)中執行。

所以你不能真正鎖定,但也沒有別的可以比賽你的代碼。

至於堆棧溢出:如果你確實有這種情況,例如。那可能會溢出的500萬線(在IE中,Number of Javascript lines executed during page load)堆棧的遞歸功能,您可以使用的0超時延遲功能:

setTimeout(function() { }, 0); 

這也是下劃線的方式defer作品。

+0

謝謝先生(或女士)!工作很好! – 2013-03-01 00:52:37

+0

不用客氣;) – metadings 2013-03-01 00:52:55