Heilemann Heilemann - 19 days ago 5
Javascript Question

AJAX call in for loop won't return values to correct array positions

I need to get a range of pages using AJAX and put them into an array, where their given place in the array is equal to the

i
of a for loop (it's a caching-like function for blog pages, and the range of the for loop is entirely variable). I'm doing something akin to the following:

var bongo = new Array();

for (i = 0; i < 10; i++) {

jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString, success: function(request) { bongo[i] = request } })

}


The problem is, that unless I add
async: false
to the .ajax options (which would make it... SJAX?), which causes the requests to basically pause the browser, going against what I'm trying to do, the i in the success callback will always end up being 11, whereas I of course want it to pour the returned data into each slot of the array from 0 to 10.

I've tried replacing the line with this:

bongo[i] = jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString }).responseText


But that made no difference.

Answer

You need a closure:

var bongo = [];
for (i = 0; i < 10; i++)
{

  (function(i)
    {
      jQuery.ajax(
        {
          type: "GET",
          url: "http://localhost",
          data: queryString,
          success: function(request) { bongo[i] = request } 
        });  
    })(i);
}

Loops are the #1 place where inline functions stump people. The bongo[i] = result isn't called until later. The value of i at that time is different (most likely 11). If you want to "trap" or "capture" the current value of i, you need to create a new scope. The only way to do that in javascript is with another function.