0
  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?

Maximus S
  • 10,759
  • 19
  • 75
  • 154
  • `.each()` won't change when the ajax calls are run. It will give you access to the `i` variable uniquely within each completion function, but your code sample and question doesn't say anything about that. – jfriend00 Apr 03 '14 at 01:21

3 Answers3

2

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();
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

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));
} 
Remento
  • 927
  • 4
  • 6
  • This will still log 1,2,3 and then the results just like in the OP's question. It will make `i` available inside the response function, but I don't think that was the OP's question. – jfriend00 Apr 03 '14 at 01:19
-1

$.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.

Adam Merrifield
  • 10,307
  • 4
  • 41
  • 58
  • 1
    `async false` is a horrible recommendation. Locks up the browser during all the ajax calls. – jfriend00 Apr 03 '14 at 01:15
  • @jfriend00 Thanks for the info. I wasn't aware of it locking up the browser, I was just aware of the option. I checked the [docs](https://api.jquery.com/jQuery.ajax/) and seen "Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active." So needless to say I won't be recommending this option anymore. – Adam Merrifield Apr 03 '14 at 01:23