Niklas9
Niklas9

Reputation: 9386

Make sure all async calls have been completed in jQuery

I have a webapp that is doing a bunch of async API calls using jQuery:s $.get and $.post methods. I need to make sure that all these have finished successfully (HTTP status code 200) before I activate a button (display: none/block).

Is there a way to make sure that there are no outstanding async calls waiting out-of-the-box in jQuery? Or do I need to keep track of this myself?

I'm using jQuery v1.8.3.

Upvotes: 0

Views: 2197

Answers (2)

Matt
Matt

Reputation: 75307

You can create a "Master Deferred", which will only resolve when all of the other Deferreds (the AJAX requests) have completed successfully;

jQuery.when(jQuery.get('/foo'), jQuery.post('/bar'), jQuery.get('/baz')).done(function () {
    $('button').show();
});

The syntax is to pass each Deferred as a parameter to jQuery.when(), which returns a Deferred which resolves when one fails, or when all of them complete.

If you don't know beforehand how many AJAX requests you have, already have them in an array, or just don't want to use the above, you can use Function.apply like so;

var ajaxRequests = [jQuery.get('/foo'), jQuery.post('/bar'), jQuery.get('/baz')];

jQuery.when.apply(jQuery, ajaxRequests).done(function () {
    $('button').show();
});

For more info, see http://api.jquery.com/jQuery.when, or http://www.mattlunn.me.uk/blog/2014/01/tracking-joining-parallel-ajax-requests-with-jquery/ (my blog)

Upvotes: 5

h2ooooooo
h2ooooooo

Reputation: 39522

From this post, you should be able to use the same code (you do not need the abortAll function, though, so it's been removed, and a check for active requests has been added):

$.xhrPool = [];
$.ajaxSetup({
    beforeSend: function(jqXHR) {
        $.xhrPool.push(jqXHR);
    },
    complete: function(jqXHR) {
        var index = $.xhrPool.indexOf(jqXHR);
        if (index > -1) {
            $.xhrPool.splice(index, 1);
        }
        if ($.xhrPool.length > 0) {
            //There are still active requests - keep the button hidden
        } else {
            //There's no more active requests - show the button
        }
    }
});

This will work for all ajax requests requested through jQuery, both with $.get, $.post and $.ajax.

Upvotes: 1

Related Questions