Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recursive calls to ajax cause memory leak?

Does the following code logic cause the original call's stack frame to contain the memory from each subsequent call (causing excessive memory usage)?

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!');
         }
     }
  });
}
like image 609
Jake Psimos Avatar asked Mar 14 '23 14:03

Jake Psimos


2 Answers

Your code is not recursive. $.ajax is asynchronous, so the stack pointer isn't waiting for bar to return.

Instead, $.ajax fires an asynchronous process, then continues until it hits either an explicit or implicit return. In your case, there is an implicit return at the end of bar.

Your function consumes no more memory than it should.

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
}
like image 51
royhowie Avatar answered Mar 25 '23 05:03

royhowie


I was curious to see if this was the case, so I tested it using a simplified version. The code below is an ajax call that binds calls to itself in its own success routine, printing the call stack each time. As it turns out, the call stack is the same each time, i.e. no memory leak.

I have a hunch that the fact that the call is asynchronous may come into play - i.e. there isn't actually any recursion since the success handler is called by the browser directly on the success of the AJAX call, not from within the last invocation of the function.

Here is the code I used to test the hypothesis:

var count = 0;

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

bar();

And here is a live JSFiddle that shows you that the call stack is exactly the same on each invocation: https://jsfiddle.net/dtrgak9o/

like image 33
Maximillian Laumeister Avatar answered Mar 25 '23 06:03

Maximillian Laumeister