Maximus S
Maximus S

Reputation: 11115

behavior of ajax call inside a for loop

  for (var i in arr) {
    console.log(i);
    $.get(searchURL, function (result) {
      console.log(result);
    }); // end of inner async request
  } // end of outer arr

In this case, I am seeing

1
2
3
result
result
result

but what I intended and expected was

1
result
2
result
3 
result

I assume this happens because each ajax call is taking longer than the entire for loop's execution. Is this right? If so, what is the conventional way of doing this?

update:

I found using jQuery's $.each function instead of for loop gives me the expected output. Is $.each function intended to work with async calls inside loops?

Upvotes: 0

Views: 271

Answers (3)

jfriend00
jfriend00

Reputation: 707746

It launches all three asynchronous ajax calls and then one by one, the results come back from them. Because they are asynchronous, no results will be processed until the current thread of javascript finishes and gets back to the event queue to start serving the arriving ajax results. The results you see has only to do with the fact that the ajax calls are asynchronous and nothing to do with how long they take to come back with the results.

If you want to run them serially, then you structure your code to call on ajax call and then, when that finishes, call the next ajax call and so on like this:

function doAjax(arr) {
    var i = 0;

    function next() {
        if (i < arr.length) {
            console.log(i);
            // do something with arr[i] here
            $.get(searchURL, function (result) {
                 console.log(result);
                 i++;
                 next();
            }); // end of inner async request
        }
    }
    next();
}

Upvotes: 2

Adam Merrifield
Adam Merrifield

Reputation: 10407

$.get is asynchronous. If you're using jQuery < 1.8 you can use async: false like so:

$.ajax({
    type:'get',
    url: searchURL,
    async: false,
    complete: function(response){
        //done
    }
});

Otherwise you could use jQuery's Deffered.

Upvotes: -1

Remento
Remento

Reputation: 927

The ajax calls are asynchronous and JS is single threaded. That means no matter how fast the server responds, the for loop will always complete first. Try passing i to your callback.

var responseHandle= function (i,result) {
      console.log(i, result);
    };

for (var i in arr {
    console.log(i);
    $.get(searchURL, responseHandle.bind(null,i));
} 

Upvotes: 0

Related Questions