2015-10-03 34 views
3

以下代碼邏輯是否會導致原始調用的堆棧幀包含每次後續調用的內存(導致內存使用量過多)?遞歸調用ajax導致內存泄漏?

function foo (arg) { 
    bar(arg); 
} 

function bar (arg) { 
    $.ajax({ 
    success: function (data) { 
     if (data['result'] == 'continue') { 
      bar(data['nextarg']); 
     } else if (data['result'] == 'done') { 
      alert('done!'); 
     } 
    } 
    }); 
} 
+0

乍一看,** **沒有,但可能依賴於瀏覽器 – WhiteHat

+0

您是否遇到任何讓你相信這是怎麼回事? – Jesse

+0

取決於什麼水平的數據[nextarg]返回繼續...您的瀏覽器將在這種情況下進行多個網絡調用,響應可能調用循環中的相同方法...您可以在服務器上做同樣的事情,並只返回最終響應。 ..對 ?或者只有在需要時纔可以進行延遲加載。你真的需要根據響應進行相同的Ajax調用嗎? – Nielarshi

回答

4

您的代碼不是遞歸的。 $.ajax是異步的,所以堆棧指針不會等待bar返回。

取而代之的是,$.ajax觸發一個異步進程,然後繼續執行,直到遇到顯式或隱式返回。在你的情況下,在bar末尾有一個隱含的回報。

你的函數消耗的內存比它應該多。

function bar (arg) { 
    // calls $.ajax, which is async, so it fires "whenever" 
    $.ajax({ 
    // when the ajax is complete/successful, this function is called 
     success: function (data) { 
     if (data['result'] == 'continue') { 
      bar(data['nextarg']); 
     } else if (data['result'] == 'done') { 
      alert('done!'); 
     } 
    } 
    }) 
    // exits immediately after 
} 
2

我很好奇,看看是否是這種情況,所以我使用簡化版本進行了測試。下面的代碼是一個ajax調用,它在自己的成功例程中將調用綁定到自身,每次都打印調用堆棧。事實證明,每次調用堆棧都是相同的,即沒有內存泄漏

我有一個預感,事實上調用異步可能會發揮作用 - 即實際上沒有任何遞歸,因爲成功處理程序直接由AJAX調用成功的瀏覽器調用,而不是從內部函數的最後一次調用。

這裏是我用來測試的假設代碼:

var count = 0; 

function bar() { 
    $.ajax("/", { 
     success: function() { 
      count++; 
      console.trace(); 
      if (count < 4) bar(); 
     } 
    }); 
} 

bar(); 

這裏是一個活的jsfiddle,顯示您的調用棧恰好在每次調用相同的:https://jsfiddle.net/dtrgak9o/

+0

這裏實際上沒有任何遞歸,因爲' $ .ajax()'是異步的,所以'bar()'在調用'success'處理程序之前完全執行。這就是爲什麼沒有堆積累的原因。這與jQuery的智能無關。這是一個簡單的Javascript的東西,當這種方式與異步回調結構。 – jfriend00

+0

@ jfriend00我編輯了我的問題以添加有關異步回調的信息,但是我忘記刪除關於jQuery的猜測。剛剛編輯出來,謝謝。 –