What Happens if jQuery $.when() AJAX Call Fails?
When you pass multiple asynchronous AJAX requests to jQuery’s
$.when() method, the master Deferred object adopts a
"fail-fast" strategy: if even a single AJAX call fails, the entire
$.when() operation rejects immediately. This article
explains how $.when() behaves during an AJAX failure, which
callbacks are executed, and how you can prevent one failing request from
breaking the rest of your operations.
The Immediate Rejection Mechanism
jQuery's $.when() behaves similarly to native
JavaScript's Promise.all(). It expects all provided
Deferred or Promise objects to resolve successfully before it marks the
master Deferred as resolved.
If any of the requests encounter an HTTP error (such as a 404, 500, or a network timeout), the following occurs:
.done()is aborted: Any callback attached via.done()or the success handler in.then()will not execute, even if all other requests succeed..fail()triggers immediately: The.fail()callback fires as soon as the first error occurs, without waiting for the remaining active requests to complete.- Arguments passed to
.fail(): The arguments received by the.fail()handler correspond directly to the specific request that failed, providing the standard jQuery error parameters:jqXHR,textStatus, anderrorThrown. - Subsequent requests are not canceled: Any other
network requests that were in flight when the failure occurred will
continue running to completion in the background. However, their results
will be completely ignored by the parent
$.when()handler.
How to Prevent One Failure from Blocking Others
If your application requires every request to finish regardless of
whether individual requests succeed or fail (similar to
Promise.allSettled()), you must intercept errors at the
individual request level before they reach $.when().
To achieve this, attach a .fail() or
.always() handler to each individual $.ajax()
call that resolves a surrogate promise or transforms the failure into a
resolved state:
function safeAjax(options) {
var deferred = $.Deferred();
$.ajax(options)
.done(function(data) {
deferred.resolve({ success: true, data: data });
})
.fail(function(jqXHR, textStatus, errorThrown) {
// Resolve instead of reject so $.when() continues
deferred.resolve({ success: false, error: textStatus });
});
return deferred.promise();
}
$.when(safeAjax({ url: '/api/items' }), safeAjax({ url: '/api/users' }))
.done(function(res1, res2) {
// This will always run, allowing you to inspect each result individually
console.log('Result 1:', res1);
console.log('Result 2:', res2);
});By ensuring each underlying Deferred resolves instead of rejecting,
$.when() will always fire its .done()
callback, giving you full control over how partial failures are handled
in your application.