5

Assuming I have the following:

function main() {

  var finished = false;

  for(var i=0; i < 3; i++) {
    do(i);
  }
}

function do(i) {
  $.ajax({
   url:"myurl.com/"+i,
   datatype:"text/xml",
   success: function() {

        // Two more layers of multiple nested $.ajax elements here
   }
  })
}

Is there some way I could pop an alert box after all the "do" are finished after the three iterations? How? Syntax would help.

3 Answers 3

14

An ajax call returns a jQuery Promise object. You could collect the output of each one in an array, and use $.when to 'bundle' the promises together.

This code is the basic idea behind what you want:

function main() {

  var finished = false;

  var defs = [];

  for(var i=0; i < 3; i++) {
    defs.push(do(i));
  }

  $.when.apply(null, defs).done(function() {
    //this code will only run when all ajax calls are complete
  });
}

function do(i) {
  var promise = $.ajax({
   url:"myurl.com/"+i,
   datatype:"text/xml",
   success: function() {

        // Two more layers of multiple nested $.ajax elements here
   }
  })

  return promise;
}

The browser can have a lot of open HTTP connections, don't let the naysayers convince you otherwise. Here is a table of maximum concurrent connections supported by browser. Let your site usage statistics be your guide, but even 2 ajax requests at once is faster than totally synchronous data requests...

Firefox 2:  2
Firefox 3+: 6
Opera 9.26: 4
Opera 12:   6
Safari 3:   4
Safari 5:   6
IE 7:       2
IE 8:       6
IE 10:      8
Chrome:     6
Sign up to request clarification or add additional context in comments.

6 Comments

Wouldn't it be simpler to just make the calls synchronous?
Then the they all take longer? That point of ajax is that you can get many calls to happen at once.
the max you can have open at once is 2... And that is not the point of ajax, it just happens to be an option.
Yeah in IE6 and FF2. Everyone else these days is way mo' betta
There is no single point of ajax. The most important benefit however imho is that you never have to write ugly form tags.
|
2

As global:

var complete = 0;

All AJAX calls;

$.ajax({
  ... //other attributes,
  complete: function(){
    complete++;
    if (complete == 3) {
      alert('all completed');
    }
  }
});

This would execute when three AJAX calls are done. However, if you need to increase it, then do so.

2 Comments

Deferreds and promises are a much cleaner way to solve this problem, especially when the number of ajax calls might be variable so you can't hardcode in 3
Globals are not needed for this problem
0

You can use an array of statuses for this:

function main() {
  var ready = new Array(3);
  for (var i = 0; i < 3; i++) {
    ready[i] = false;
  }

  for (var i = 0; i < 3; i++) {
    do(i, ready);
  }
}

function do(i, ready) {
  $.ajax({
   url:"myurl.com/"+i,
   datatype:"text/xml",
   success: function() {
     // If there are multiple layers then the next statements should be executed in the last layer.
     ready[i] = true;
     if (isAllReady(ready)) {
       alert("All done!");
     }
   }
  })
}

function isAllReady(ready) {
  var allReady = true;
  for (var i = 0; i < 3; i++) {
    if (!ready[i]) {
      allReady = false;
    }
  }
  return allReady;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.