-1

Just wondering how to make sure Ajax in for loop returns values in order. For example, I have this code:

for(var i=0; i < list.length; i++) {
  $.ajax({
    url: ...,
    type: 'get',
    dataType: "jsonp",
    success: function(data) {
      ...
      var html = '...';
      $('#some-div').append(html);
    })
}

And when I run it, result sometimes run in right order, but sometimes it doesn't. I don't know what to do. Please someone helps me fix this problem. Thanks!

  • 1
    Unless you chain the requests to run one after the other there is no way to 100% guarantee the order of their execution. They will be sent to the server in the order 1, 2, 3, however the server may not receive or process them in that order, and processing time may also vary, so the responses may come back in 2, 3, 1 for example. – Rory McCrossan Apr 09 '15 at 15:41
  • 1
    i would try to combine those requests all into one if possible. seeing ajax in loops like this is usually a red flag. – Rooster Apr 09 '15 at 15:41
  • @john26blue check my answer, it should work. – Vinod Kumar Apr 09 '15 at 15:52

2 Answers2

2

They don't return in order, and that is out of your control unless you queue the calls sequentially (which will slow down the whole process) but that does not mean you can't assemble the results in the correct order.

Add a scoping function and use a temp container appended immediately (in order) and filled in later after the Ajax completes:

for(var i=0; i < list.length; i++) {
  function(i){
      var $div = $('<div>');
      $('#some-div').append($div);
      $.ajax({
       url: ...,
       type: 'get',
       dataType: "jsonp",
       success: function(data) {
         ...
         var html = '...';
         $div.append(html);
    })
  }(i);
}

The scoping function gets immediately executed, passing i as a local i parameter (if needed). This is what they call an IIFE (Immediately Invoked Function Expression).

Alternatively, you can then use the value of i to determine where in sequence to insert the particular result. Personally I like the first "placeholder" option.

Note: As @Rooster points out, you are often better off making a single Ajax call that returns multiple items (already in sequence).

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
1

Generally to do this you will have to call the 2nd request on the success of first request and 3rd on the success of the 2nd.. so on..

var urls = ["http://www.google.com", ...];
function callAjax(ajaxReqId){
   $.ajax({
    url: urls[ajaxReqId], //keep your urls in an array, Take the URL from the array with the index received as parameter.
    type: 'get',
    dataType: "jsonp",
    success: function(data) {
      ...
      var html = '...';
      $('#some-div').append(html);

      //On success, we are ready to go to next ajax call.
      ajaxReqId++; //So, we increment the index
      if(ajaxReqId < urls.length) //Ensure that we don't cross the maximum requests we intent to call.
          callAjax(ajaxReqId); //Call the same function we used to call request 1. Just with incremented Id.
    })
}

callAjax(0); //Call the very first ajax request by index.

This should help you...

Edit: Just a note: This is still async and does the job as you want... waits for the response of earlier request before proceeding to the next.

Vinod Kumar
  • 981
  • 1
  • 6
  • 14
  • The downside of this technique is that you slow down the overall process by chaining the loads. Much faster response to use placeholders and fill them out as they return. – iCollect.it Ltd Apr 09 '15 at 15:53
  • True... but to execute ajax requests one after the other on succession... I don't see any other options. Please let me know if I am missing something... – Vinod Kumar Apr 09 '15 at 15:56
  • See my alternate answer. If the end result is just the display order, placeholders will do the trick. – iCollect.it Ltd Apr 09 '15 at 15:57
  • Thank you very much. This is what I'm looking for. The code is so easy but I can't figure out :D – john26blue Apr 10 '15 at 12:32
  • You are welcome :) I have added more comments, to make it even easier to understand the logic. – Vinod Kumar Apr 10 '15 at 12:53