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)?
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.
It isn't pretty, but you could have a global "completed" variable for each ajax call to set when complete. Each call would also check whether both variables were set, and if so, call your always function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With