0

my web app as the following structure in ajax requests:

 $.ajax({
    type : "GET",
    url: '...',
    dataType: "xml",
    success: function(xml) {

                $.ajax({
                    type : "GET",
                    url : "....",
                    dataType : "xml",

                    success : function(xml) {

                    },
                    error : function(xhr) {
                        alert(xhr.responseText);
                    }
                });
                $.ajax({
                    type : "GET",
                    url : "....",
                    dataType : "xml",

                    success : function(xml) {
                    },
                    error : function(xhr) {
                        alert(xhr.responseText);
                    }
                });

                $.ajax({
                    type : "GET",
                    url : "...",
                    dataType : "xml",

                    success : function(xml) {
                    },
                    error : function(xhr) {
                        alert(xhr.responseText);
                    }
                });


        }
 });

I need all the resquests that are beeing made here to finish before i do something else. Because i need them to load content into a div. and then append that to a html element in my code. And i dont want to use (document).ajaxStop because that will ruin my code later on.

How can i achieve this?

João
  • 331
  • 1
  • 3
  • 17

3 Answers3

1

jQuery's $.ajax returns a promise ($.Deferred) by default. So you don't have to use callbacks and you can use these promises instead. Then using the $.when function you can create a new promise which will wait for these 3 promises to finish and the do all actions you need.

Look at the example in the bottom of the linked page to see how it works.

Edit: If the documentation is right then it should look like this:

$.ajax({
  type : "GET",
  url: '...',
  dataType: "xml"
})
  .then(function (xml) {
    return $.when(
      $.ajax({
        type : "GET",
        url : "....",
        dataType : "xml"
      }),
      $.ajax({
        type : "GET",
        url : "....",
        dataType : "xml"
      }),
      $.ajax({
        type : "GET",
        url : "...",
        dataType : "xml"
      })
    );
  })
  .then(function (res1, res2, res3) {
    var xml1 = res1[0], xml2 = res2[0], xml3 = res3[0];


  });

But I didn't test it so I don't know if it's really right.

Razem
  • 1,421
  • 11
  • 14
1

You can use differed($.Deferred) Objects to make your code look more clean,

Every $.ajax request returns you a differed object, and use them with $.when and .done() combination like the following

$.when(req1, req2, req3).done(function (resp1, resp2, resp3) {

    //This will be executed on the success of all three requests
})

In your case you can do as follows

var req1 = $.ajax({type:"GET", url: "..."});

req1.done(function (resp1) {

    // This will execute after the first request is done
    var req2 = $.ajax({type:"GET", url: "..."}),
        req3 = $.ajax({type:"GET", url: "..."}),
        req4 = $.ajax({type:"GET", url: "..."});

    $.when(req2, req3, req4).done(function (resp2, resp3, resp4) {

        // when other three request are done
    });

    // If there are arbitrary number of requests, please consider the following
    var requestsArray = [],
        numberOfRequests = 10;

    for (var i=0; i<numberOfRequests; i++) {

        var request = $.ajax({type:"GET", url: "..."});
        requestsArray.push(request);
    };

    $.when.apply(null, requestsArray).done(function () {

        // You can collect the responses in the same order from `arguments`
        var responses = arguments;
    });
});

Deferred objects provide a very nice way to handle callbacks, To know more on Deferred objects check this out http://api.jquery.com/category/deferred-object/

  • and resp1, resp2 and resp3 would be the json responses of those ajax requests? – João Jul 27 '14 at 15:50
  • it never enters in the req1.done(function (resp1) { – João Jul 27 '14 at 16:11
  • i changed datatype to text and it returns the page itself in html instead of the xml i get when i do a normal ajax request without the done function – João Jul 27 '14 at 16:35
  • 1
    Ok thhx i got it to work. what if i dont know how many requests i will make? or i will have a variable number of requests? – João Jul 27 '14 at 16:54
  • push all requests into an array and use `apply` to invoke, like $.when.apply(null, requests_array).done(function(){ var responses=arguments; }) – Prashanth Pamidi Jul 27 '14 at 17:30
  • pls edit that into your question? for better understanding? i really liked your answer. because it was simple and full example. – João Jul 27 '14 at 17:31
  • where is the arguments coming from? – João Jul 27 '14 at 17:44
  • Every function that is invoked gets two secret variables 1)`this` 2)`arguments` – Prashanth Pamidi Jul 27 '14 at 17:46
  • `this` contains the context in which the function is invoked and `arguments` is an array like( but not array ) data structure that contain all the arguments that are passed to the function. – Prashanth Pamidi Jul 27 '14 at 17:48
  • To know precisely what would `this` contain when ever you invoked a function, please see http://doctrina.org/Javascript-Function-Invocation-Patterns.html. – Prashanth Pamidi Jul 27 '14 at 17:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58113/discussion-between-joao-and-prashanth-pamidi). – João Jul 27 '14 at 18:12
0

I think you can use Jquery Deffer, like that. Serial call

  $.ajax('http://echo.jsontest.com/id/1')
  .then(function(result){
      console.log(JSON.stringify(result));
      return $.ajax('http://echo.jsontest.com/id/2')
  }).then(function(result){
      console.log(JSON.stringify(result));
      return $.ajax('http://echo.jsontest.com/id/3')
  }).then(function(result){
      console.log(JSON.stringify(result));
  });

Paralel call

$.when(
     $.ajax('http://echo.jsontest.com/id/1'),
     $.ajax('http://echo.jsontest.com/id/2'),
     $.ajax('http://echo.jsontest.com/id/3')
 ).then(function(result1, result2, result3){
     console.log(JSON.stringify(result1[0]));
     console.log(JSON.stringify(result2[0]));
     console.log(JSON.stringify(result3[0]));
 })
Isabek Tashiev
  • 1,036
  • 1
  • 8
  • 14