2015-09-01 60 views
1

請考慮以下幾點:遞歸函數和setTimeout的VS的setInterval

$(document).ready(function() { 
    var promise; 

    (function refresh(){ 
     promise = loadInfo(); 
     promise.done(function() { 
      $.each(loadedData, function(key, value){ 
       $('#' + key + ' div.info').html(value.label); 
      }) 
      // Call itself for next iteration 
      window.setTimeout(refresh, 5 *1000); 
     }) 
    })() 
}) 
  • 你覺得每次迭代創建一個新的變種promise或他們都重複使用相同的嗎?
  • 如果一個新的變種是針對每次迭代創建的,我可以有過載加班費(堆棧溢出!!!))?該應用程序顯示數據,並應該對長時間
  • 我也有另一個版本setInterval((function refresh(){...}), 5 *1000)沒有setTimeout的,哪一個是更好地運行?思考?

謝謝

+0

你顯示什麼不是傳統意義上的遞歸,而是 - 鏈式調用與延遲,因此,堆棧溢出不會發生 – Igor

+0

@Igor自刷新函數調用自身,無論是延遲一段時間後還是不行,仍然是遞歸的。 –

+0

@ Jonathan.Brink - 不,刷新函數不調用自身 – Igor

回答

2

由於承諾變量上面的刷新功能是通過封閉可用,並且將被重新使用的聲明,這樣應該不會造成堆棧溢出,但loadInfo的實施將確定是否每次都創建一個新變量。

這可能有助於揭示JavaScript和變量範圍的一些輕:How do JavaScript closures work?

也許稍微清理版本看起來是這樣的:

$(document).ready(function() { 
    (function refresh(){ 
     loadInfo().done(function(loadedData) { 
      $.each(loadedData, function(key, value){ 
       $('#' + key + ' div.info').html(value.label); 
      }); 
      // Call itself for next iteration 
      window.setTimeout(refresh, 5 *1000); 
     }); 
    })(); 
}); 

使用的setInterval可能更容易閱讀一些眼睛,但我認爲你的setTimeout方法很好。

+0

不錯!但是很快:爲什麼要將loadedData作爲變量傳遞給回調函數?它實際上是一個已經可用的全局變量。 – zwan

+0

您可能會有一個合理的理由將其作爲全局變量。我只是想,如果有可能避免全局變量這樣做。儘管如果它不利於您的邏輯流程,請隨時留下。 –

0

的setTimeout在當前的代碼將等待功能完成,然後等待指定的時間,然後調用刷新功能。

的setInterval將保持通話的給定時間後的功能而不論該功能是否已完成其執行或不

1

的setInterval確保定期請求(但不保證響應命令),但的setTimeout(代碼)不能保證這一點。如果響應時間很長,等待時間也會延遲。另外,如果您的loadInfo()請求失敗,則需要更多代碼來處理下一個請求。

的決定權在你的服務器環境和應用程序的優先級。

請參閱我的setTimeout代碼,如果它會幫助(性能和準確性之間)。

$(document).ready(function() { 

    // for api 
    function repeatLoad(cb) { 

     var bindedRepeatLoad = repeatLoad.bind(this, cb); 
     var repeat = setTimeout.bind(this, bindedRepeatLoad, 5*1000); 

     loadInfo() 
     .done(cb) 
     .done(repeat) 
     .error(repeat); 
    } 

    // for view 
    function render(loadedData) { 
     $.each(loadedData, function(key, value){ 
      $('#' + key + ' div.info').html(value.label); 
     }); 
    } 

    // for app logic, only 1 line is needed. 
    repeatLoad(render); 
}); 
+0

太棒了!我覺得我需要提高自己的JS知識。謝謝!不過,我接受Jonathan.Brink,因爲這對我來說更容易理解。 – zwan

+0

@ zwan謝謝,,,那只是我的風格代碼。我喜歡綁定函數,因爲它使得代碼少一點,但有時綁定函數使它一見難識。 – ssohjiro