23

I have used promises in jQuery slightly before - but I am having trouble applying it to this scenario. I prefer to use the $.when() and $.done() methods to achieve this.

From what I understand I need to build a $.Deferred object which logs the requests and when those requests are finished - fire the callback. In my code below the callback is firing before the ajax requests and not after - maybe I just need some sleep

I know my code is incomplete I have been struggling to apply it with the addition of the for loop.

http://jsfiddle.net/whiteb0x/MBZEu/

var list = ['obj1', 'obj2', 'obj3', 'obj4', 'obj5'];
var callback = function() {
  alert("done");
};
var requests = [];

var ajaxFunction = function(obj, successCallback, errorCallback) {
  for(i = 0; i < list.length; i++) {
    $.ajax({
      url: 'url',
      success: function() {
            requests.push(this);
      }
    });
  }
};
$.when($.ajax(), ajaxFunction).then(function(results){callback()});
1

2 Answers 2

58

The arguments to $.when should be the return value of $.ajax, which also doesn't need to be called separately -- that makes no sense. You want something like this:

for (i = 0; i < list.length; i++) {
   requests.push($.ajax(...));
}
$.when.apply(undefined, requests).then(...)

The reason that .apply is needed is because $.when can take multiple arguments, but not an array of arguments. .apply expands essentially to:

$.when(requests[0], requests[1], ...)

This also assumes that the requests can be completed in any order.

http://jsfiddle.net/MBZEu/4/ -- notice that 'done' is logged to the console after all of the success messages.

Sign up to request clarification or add additional context in comments.

4 Comments

how to handle all the results at once?
$.when.apply(undefined, requests).done(function(response1, response2, ...){ if(response1[1]=="success") {// DoSomething with response1[0]} });
Still, how to get all the responses in an array? You cannot expect one to know how many responses are going to be there before hand.
As @MKYung asked, it could be a problem to handle the results... because, if you have just one element in the list of requests you'll got one retuning result in the method done but divided into three parameter jqXHR.done(function( data, textStatus, jqXHR ) { ... });. But with multiple requests you got all the three parameters wrapped in arrays e.g. jqXHR.done(function( [data, textStatus, jqXHR], [data, textStatus, jqXHR], ... ) { ... });. To handle it inside the done method you have to know the count of requests, in this case list.length to decide how to parse the results...
9

I share an easy example that could help you to handle multiple requests and their responses:

var arr = [
    $.ajax({url:"test1.php"}),
    $.ajax({url:"test2.php"}),
    $.ajax({url:"test3.php"})
];
$.when.apply( undefined, arr ).then(function() {
    var objects=arguments;
    console.dir(objects);
});

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.