2011-11-24 29 views
0

我正在JavaScript中做一個非常簡單的Comet-like long polling 下面的代碼似乎工作,但它是遞歸調用自己和吃資源?我如何看?下面的代碼是遞歸地使用內存

編輯:市價修改Dogberts建議代碼

$(document).ready(function() { 
    function doSuccess(data) { 
     $('#res').html(data.time + "<br/>" + data.data); 
     startAjax(); 
    } 
    function doError(jqXHR, textStatus, errorThrown) { 
     $('#res').html(textStatus + ":" + errorThrown); 
     startAjax(); 
    } 
    function startAjax() { 
     $.ajax({ 
      url: 'http://127.0.0.1:12345/', 
      dataType: 'jsonp', 
      success: doSuccess, //Edit: updated as per Dogbert's suggestion 
      error: doError 
     }); 
    } 
    startAjax(); 
}); 

我已經運行http://home.orange.nl/jsrosman/反對它,它看起來是OK那裏(我只是在專業偏執)startAjax調用(以及callsBack)要成功哪個叫startAjax

回答

3

不,這不應該吃任何額外的資源。舊請求完成後,您正確地調用該方法。

在一個側面說明,這

 success: function (data) { 
      doSuccess(data); 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      doError(jqXHR, textStatus, errorThrown); 
     } 

可以寫成

success: doSuccess, 
error: doError 
+0

在我原來的正式更新 - THX – Andiih

1

對我來說,它看起來確定:每一個新的請求發出的舊過期

0

後最初評論你的問題,但它比我預期的要長一點...

這看起來像fi對於內存泄漏而言,ne對我來說沒有任何變量,所以垃圾收集器沒有問題。

但是,由於此方法的遞歸性質,您最終可能會遇到堆棧溢出問題 - 它從不「最終」展開堆棧。你能否使用setTimeout來定期啓動這個過程?

+0

這是我擔心的 - 是WickyNilliams正確的嗎?或者@Dogbert和Nicola – Andiih

+0

代碼非常簡單,所以我不認爲我誤解了事情 - 所以最終會發生堆棧溢出。如果您將示例運行時間足夠長(並且您的服務器響應速度足夠快以實現此目的),則應該注意這一點。 – WickyNilliams

1

該代碼沒有遞歸,startAjax在被調用後立即退出。儘管爲了最大限度地減少內存使用,但可以不必在每次調用時重新定義函數,但由於無法引用它們,所以最終舊函數總是會被刷新。 @ Dogbert的答案顯示瞭如何避免重新定義函數,但沒有關鍵,因爲沒有形成永久性關閉。

閉合成形定義爲:當外部函數被調用時定義了一個內部函數,並且(那些)內部函數在外部函數退出後可用。

現在,如果您要在同步模式下執行ajax,那麼startAjax將永遠不會退出,並且它會間接調用更多startAjax,並且您最終會達到最大調用堆棧大小。更何況你的用戶界面將被鎖定100%的時間。

例如,在谷歌瀏覽器運行此,您將得到:

RangeError: Maximum call stack size exceeded

function success(){ 
startAjax(); 
} 

function error(){ 
startAjax(); 
} 

function startAjax(){ 
synchronousAjax(success, error); 
} 

function synchronousAjax(success, error){ 
Math.random() < 0.5 ? success() : error(); 
} 

startAjax();