Search code examples
javascriptjqueryjquery-deferred

jquery deferred - wait until two calls complete


I am looking for a way to do a callback after two ajax calls completes:

$.when(
    call1(),
    call2()
).always(function() {
    // Here I want to be sure the two calls are done and to get their responses 
);

The catch is that one of the calls might fail. So, in my code the always will invoked without waiting to the other call.

How can I wait for both calls to done (success or failure)?


Solution

  • Here is something that should do the trick:

    $.whenAllDone = function() {
        var deferreds = [];
        var result = $.Deferred();
    
        $.each(arguments, function(i, current) {
            var currentDeferred = $.Deferred();
            current.then(function() {
                currentDeferred.resolve(false, arguments);
            }, function() {
                currentDeferred.resolve(true, arguments);
            });
            deferreds.push(currentDeferred);
        });
    
        $.when.apply($, deferreds).then(function() {
            var failures = [];
            var successes = [];
    
            $.each(arguments, function(i, args) {
                // If we resolved with `true` as the first parameter
                // we have a failure, a success otherwise
                var target = args[0] ? failures : successes;
                var data = args[1];
                // Push either all arguments or the only one
                target.push(data.length === 1 ? data[0] : args);
            });
    
            if(failures.length) {
                return result.reject.apply(result, failures);
            }
    
            return result.resolve.apply(result, successes);
        });
    
        return result;
    }
    

    Check out this Fiddle to see how it works.

    Basically it waits for all Deferreds to finish no matter if they fail or not and collects all the results. If we have failures, the returned Deferred will fail with a list of all failures and resolve with all successes otherwise.