0
var request3 = 
window.SendAjax(window.siteRoot + "Home/GetTweets", "{}", function(msg) {
    //tweet
    $.each(msg, function(i, value) {
       ...

    });
    console.log("loop done");
});


$.when(request1, request3).then(function () {
  console.log(feedItems);
});

I'm trying to use the $.when() jQuery method. I have 3 AJAX methods that get data then perform a loop with the data. The $.when is executing when that AJAX async is done, I need it to wait until the loops are done. I didn't show ALL the code, but there are 3 AJAX calls that fetch data then do loops. When all 3 are done, THEN do something. Thoughts?

Mark
  • 2,543
  • 6
  • 33
  • 44

3 Answers3

2

I assume SendAjax() looks like this:

function SendAjax(url, data, callback) {
    return $.ajax({
        ...
        success: callback,
        ...
    });
}

If so, change it to something like this:

function SendAjax(url, data, callback) {
    var def = $.Deferred();
    return $.ajax({
        ...
        success: function() {
            callback();
            def.resolve();
        },
        ...
    });
    return def.promise();
}

Then you can do this:

var ajax1 = SendAjax(...);
var ajax2 = SendAjax(...);
var ajax3 = SendAjax(...);

$.when(ajax1, ajax2, ajax3).done(function() {
    //do stuff
});
Jason P
  • 26,984
  • 3
  • 31
  • 45
  • This is pretty much correct, though I don't see why wrap the ajax call. Simply pass each ajax promisse to the when function (it can take several). This will resolve once one query fails or all succeed: $.when($.ajax(paramsA), $.ajax(paramsB)).then(mycompletionFunc) – Gaute Løken Aug 16 '13 at 17:38
  • I'm not sure why he has a convenience function, but he does, so I tried to work with it. – Jason P Aug 16 '13 at 17:39
  • 1
    You don't need the extra `$.Deferred()`do you? returning `$.ajax()` will suffice since jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface – omma2289 Aug 16 '13 at 17:46
  • 2
    He wants to wait until the callbacks are finished, not just the ajax calls. – Jason P Aug 16 '13 at 17:50
  • Aha.. I didn't notice that detail, Jason P. Good catch =) – Gaute Løken Aug 16 '13 at 18:12
0

Simplest thing is a counter and check:

var counter = 0;

$.ajax('....', function(data) {
    ... do your processing loop here
    counter++;
    if (counter >= 3) {
        do_the_post_counter_stuff();
    }
});

When each the ajax response handler finishes, it increments the counter and checks if it's past the limit. If it is past the limit, it just calls your "move onwards" function.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • I think he's saying he as three different ajax functions, not calling the same one three times. – Jack Aug 16 '13 at 17:27
  • That would work if there was only 1 ajax call, but there are 3 and you don't know in which order they will get done. – Mark Aug 16 '13 at 17:27
  • Doesn't matter. just put the counter increment/check into each ajax calls's response handlers, then. @mark: you NEVER know what order multiple ajax calls will finish in anyways. – Marc B Aug 16 '13 at 17:30
  • Oh, right I see that now. I didn't see the global counter var. Guess that should work. – Mark Aug 16 '13 at 17:34
0

I just ran into a similar problem myself. I was running a series of ajax requests in a while loop. Some calls were not being made! It was killing me!! My conclusion was that my browser -- Google Chrome -- ignores "duplicate" requests.

Take a look at this pseudo code:

while (i < ajaxCallArray.length) {
    currentAjaxObject = ajaxCallArray[i];
    ajaxPost = $.post(currentAjaxObject.url, function(data) {
    //response data needs to go into a function such that each request gets its own "data" variable created.otherwise it just overwrites data!!
    processAjaxResponse(data, currentAjaxObject);
        },"json");
i++;
}

If ajaxCallArray[0].url = "http://www.google.com", ajaxCallArray[1].url = "http://www.google.com", and ajaxCallArray[2].url = "http://www.google.com" the browser will only actually make 1 call!!

The solution: You have to do something like ajaxCallArray[0].url = "http://www.google.com?count=0", ajaxCallArray[1].url = "http://www.google.com?count=0", and ajaxCallArray[2].url = "http://www.google.com?count=0" even if you dont use those url parameters, just put something to make them distinct. That way the browser will process all the calls, even if they are done instantly.

Hope this helps!!

Federico
  • 6,388
  • 6
  • 35
  • 43