deferred.always() adds handlers that run when a Deferred is either resolved or rejected (since jQuery 1.6). Ideal for shared cleanup. Returns the Deferred so you can chain. Accepts a function or an array of functions.
Remember
dfd.done(onSuccess) // resolve only
dfd.fail(onError) // reject only
dfd.always(onCleanup) // resolve OR reject
// Official AJAX-style cleanup:
$.get("test.php").always(function () {
// hide spinner — ignore args
});
Attach outcome-specific handlers, then one shared cleanup.
Create a Deferred (or use a jqXHR from $.ajax() / $.get()).
Register done() / fail() for success and error UI.
Register always(fn) for cleanup that must run either way.
Settle with resolve() / reject() (or wait for AJAX to finish).
Piece
Required?
Role
Deferred / jqXHR
Yes
Object that will settle
alwaysCallbacks
Yes
Function or array of functions
Return
—
Same Deferred (chainable)
Pseudocode
Pseudocode
dfd = Deferred (pending)
alwaysQueue = []
always(fn or [fn…]):
append to alwaysQueue
if dfd already settled:
run fn now with settle args
return dfd
resolve(args…) / reject(args…):
mark settled
run done OR fail handlers
run alwaysQueue in order with args
Three registrations. Each always() queues one handler.
Resolve. The Deferred settles successfully.
Order preserved. Handlers run FIFO.
Alternative. You can also pass an array: always([fn1, fn2]).
Edge Cases & Pitfalls
Check these before putting logic inside always().
args
Do not parse settle arguments
Resolve and reject payloads often differ. Keep argument-aware logic in done / fail.
pending
Never runs while pending
always() waits for settle. Attaching it early is fine — it queues until resolve/reject.
late
Late attach still runs
If the Deferred already settled, a new always() callback runs immediately (memory-style queues).
errors
Throwing inside always
An exception in one always handler can interrupt later always callbacks in the same settle pass — keep cleanup defensive.
finally
Not identical to Promise.finally
Similar idea, but always() is jQuery Deferred-specific and receives settle arguments (unlike native finally).
Compatibility
Browser Support
deferred.always() is part of jQuery’s Deferred API (since 1.6). It works in any browser where your jQuery build runs — the queue lives in jQuery, not as a separate browser API.
✓ jQuery 1.6+ · Browsers
jQuery deferred.always()
Supported in jQuery 1.6+, including 2.x and 3.x, across Chrome, Firefox, Safari, Edge, and other browsers with jQuery loaded.
100%With jQuery loaded
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
deferred.always()Browsers
Bottom line: Safe wherever jQuery 1.6+ is loaded. Use always() for shared cleanup; keep argument-aware work in done() / fail().
Analysis
Performance Notes
Operation
Cost
Best for
always(fn)
O(1) queue
Registering cleanup
Settle + always handlers
O(n)
Running all always callbacks
Duplicated cleanup in done+fail
2× code paths
Avoid — prefer one always
Registering always() is cheap. Cost shows up if cleanup does heavy DOM or network work. Keep always handlers light (hide spinner, unlock UI) and put expensive outcome-specific work in done / fail.
Remember
Key Takeaways
Role: run after resolve or reject — perfect for cleanup.
Args: prefer ignoring them; use done/fail for known shapes.
AJAX: chain .always() on jqXHR from $.get / $.ajax.
Pattern:done → fail → always for clean request UI.
One line:always() is the Deferred cleanup hook — run it whether you win or lose.
Frequently Asked Questions
always() registers a callback that runs when the Deferred settles — either resolved or rejected. Use it for shared cleanup such as hiding spinners or re-enabling buttons.
done() runs only on resolve; fail() only on reject. always() runs after either outcome. It does not run while the Deferred is still pending.
Usually no. Official docs warn that resolve and reject arguments are often different shapes. Prefer always() for side effects that ignore args; use done() or fail() when you need the well-known argument order.
Yes. jqXHR objects implement the Deferred interface, so you can chain .done(), .fail(), and .always() — a common pattern for UI cleanup.
Conceptually similar: both run after success or failure. always() is jQuery-specific; native finally() is the modern standard outside jQuery.
Yes. Pass multiple functions or call always() several times. Callbacks run in registration order when the Deferred settles.