2009-07-20 55 views
3

我不太熟悉每個瀏覽器上每個javascript實現的細節。然而,我知道使用setTimeout,傳入的方法會在單獨的線程中調用。那麼在一個方法內部遞歸地使用setTimeout會導致堆棧無限增長,直到它導致堆棧溢出?或者它會創建一個單獨的調用堆棧,並在焦點失去時摧毀當前幀?這是我想知道的代碼。Javascript投票服務器。這會導致堆棧溢出嗎?

function pollServer() 
{ 
    $.getJSON("poll.php", {}, function(data){ 
     window.setTimeout(pollServer, 1000); 
    }); 
} 

window.setTimeout(pollServer, 0); 

我想輪詢服務器每秒左右,但不想浪費CPU週期以「堵循環」 - 我也不想設置多長時間,用戶可以訪問一個時限或者在他們的瀏覽器死亡之前。

編輯

用Firebug,我設置一些斷點,並通過查看「腳本 - >棧」面板中看到調用堆棧是真的只是「pollServer」,它不會每次通話成長。這很好 - 但是,JS的其他實現的行爲有什麼不同?

回答

2

我不確定它是否會產生堆棧溢出,但如果週期不變,我建議您使用setInterval

這就是prototype如何實現它的PeriodicalExecuter

// Taken from Prototype (www.prototypejs.org) 
var PeriodicalExecuter = Class.create({ 
    initialize: function(callback, frequency) { 
    this.callback = callback; 
    this.frequency = frequency; 
    this.currentlyExecuting = false; 

    this.registerCallback(); 
    }, 

    registerCallback: function() { 
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); 
    }, 

    execute: function() { 
    this.callback(this); 
    }, 

    stop: function() { 
    if (!this.timer) return; 
    clearInterval(this.timer); 
    this.timer = null; 
    }, 

    onTimerEvent: function() { 
    if (!this.currentlyExecuting) { 
     try { 
     this.currentlyExecuting = true; 
     this.execute(); 
     } finally { 
     this.currentlyExecuting = false; 
     } 
    } 
    } 
}); 
+0

這看起來很穩固,與我的實現類似。如果這是保證不會導致SO,那麼看起來我的代碼也不會。 – nlaq 2009-07-20 19:04:26

0

setTimeout不會增加調用堆棧,因爲它會立即返回。至於你的代碼是否會在任何瀏覽器中無限期地運行,我不確定,但似乎很可能。

1

setTimeout將在稍後的某個時間在事件泵循環中執行。傳遞給setTimeout的函數不是連續的。

如果你停下來想一想,有什麼有用的目的或證據是在那裏,調用堆棧是由超時函數共享的。

  • 如果他們被共享什麼棧將從setter共享到超時功能?
  • 鑑於二傳手可以做一些回報和彈出一些幀 - 會傳遞什麼?
  • 超時功能是否阻止原始線程?
  • 執行超時後執行setTimeout函數後的語句嗎?

一旦你回答了這些問題,很明顯答案是NO

0

看看jQuery的「SmartUpdater」插件。

http://plugins.jquery.com/project/smartupdater

使用以下功能:

  • 停止() - 停止更新。
  • restart() - 在重置時間間隔爲minTimeout時暫停後開始更新。
  • continue() - 在不重置時間間隔的情況下暫停後開始更新。
  • 狀態屬性 - 顯示當前狀態(運行|停止|未定義)
  • 更新只有當新的數據是從舊的不同。
  • 每當數據未被改變時,乘以時間間隔
  • 處理ajax故障通過停止在「maxFailedRequests」之後請求數據。