The always() method attaches a callback that runs when a jQuery Deferred settles — whether the operation succeeded or failed. This tutorial covers syntax, five worked examples, comparisons with done() and fail(), and practical cleanup patterns for AJAX and custom async tasks.
01
Syntax
dfd.always(fn)
02
On resolve
Cleanup after success
03
On reject
Cleanup after failure
04
vs done/fail
Shared final step
05
AJAX
Hide spinners
06
Chainable
Returns Deferred
Fundamentals
Introduction
Asynchronous work — AJAX calls, animations, timers — rarely finishes instantly. jQuery’s Deferred object lets you register handlers for success (done()), failure (fail()), and progress (progress()). The always() method fills a different role: it runs code you need no matter which outcome occurred.
Typical jobs for always() include hiding loading indicators, re-enabling submit buttons, closing modal overlays, and writing audit logs. Keep outcome-specific logic in done() or fail(); keep shared teardown in always().
Concept
Understanding the always() Method
always() is part of jQuery’s Deferred Object API. When you call deferred.always(callback), jQuery queues your function and invokes it once the Deferred enters a resolved or rejected state. It does not run while the operation is still pending.
The callback receives the same arguments passed to resolve() or reject(). That makes it easy to log context, though most cleanup code ignores those values.
💡
Beginner Tip
Think of always() as a finally block for promises: one place for work that must happen whether the async task succeeded or threw an error.
Splitting cleanup into small functions keeps each handler focused. Alternatively, call one function from a single always() callback if you prefer fewer registrations.
Applications
🚀 Use Cases
Cleanup tasks — close connections, release locks, or reset module state after async work completes.
Loading indicators — show spinners on start, hide them in always() so failures do not leave the UI stuck.
Logging and monitoring — record that a request finished, with timing metadata, independent of success.
UI updates — re-enable buttons, remove disabled classes, or restore focus after form submission.
Fallback preparation — pair with fail() for error messages while always() handles shared teardown.
🧠 How always() Fits the Deferred Lifecycle
1
Pending
Async work runs. always() callbacks are queued but not invoked yet.
Wait
2
Settled
Deferred resolves or rejects. Matching done() or fail() handlers run first.
Outcome
3
always() runs
Every registered always callback executes in order with resolve/reject arguments.
Cleanup
=
✅
Consistent UI
Shared teardown runs once per operation — success or failure — without duplicated code.
Important
📝 Notes
always() does not run while the Deferred is still pending.
Put outcome-specific logic in done() or fail(), not in always().
jqXHR from $.ajax() supports the same chaining methods as a Deferred.
Returning a new Deferred from an always() callback does not change the original Deferred’s state.
In greenfield code without jQuery, consider native Promise.prototype.finally() for the same pattern.
Compatibility
Browser Support
deferred.always() is part of jQuery’s Deferred implementation, available in jQuery 1.5+. It works wherever jQuery runs — including legacy browsers when you ship a supported jQuery build.
✓ jQuery 1.5+
jQuery Deferred.always()
Supported in all jQuery 1.x, 2.x, and 3.x releases. Behavior is consistent across browsers because jQuery normalizes the Deferred API.
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()Universal
Bottom line: Safe in any project that already includes jQuery. For new apps without jQuery, use native Promises and finally() instead.
Wrap Up
🎉 Conclusion
The deferred.always() method is the right tool when you need code to run after an asynchronous operation completes — whether it succeeded or failed. It keeps cleanup DRY and makes AJAX-driven UIs more reliable.
Practice the five examples above, then explore done() and fail() for outcome-specific handlers on the same Deferred chain.
Forget that arguments mirror resolve/reject values
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about always()
Reliable cleanup for jQuery async workflows.
5
Core concepts
📝01
Syntax
dfd.always(fn)
API
✅02
Resolve
Runs after done
Success
❌03
Reject
Runs after fail
Error
🔄04
Cleanup
Spinners, locks
Pattern
🔗05
Chain
done → always
AJAX
❓ Frequently Asked Questions
always() registers a callback that runs once the Deferred settles — either resolved (success) or rejected (failure). 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, in the same order as other handlers for that event. It does not run while the Deferred is still pending.
Yes. jQuery passes the resolve or reject arguments to every always callback, matching whichever path the Deferred took.
Yes. jqXHR objects implement the Deferred interface, so you can chain .done(), .fail(), and .always() on AJAX requests — a common pattern for UI cleanup.
Conceptually similar: both run after success or failure. always() is jQuery-specific and integrates with the Deferred API; native finally() is the modern standard outside jQuery.
Yes. Each always callback you register is queued and executed in order when the Deferred resolves or rejects.
Did you know?
Before native Promise.finally() was widely available, jQuery’s always() was the go-to way to hide loading spinners after AJAX calls — one callback instead of duplicating cleanup in both success and error handlers.