jQuery Deferred

Beginner
⏱️ 14 min read
📚 Updated: Jul 2026
🎯 18 Tutorials
Async API

What You’ll Learn

Asynchronous code runs in the background — AJAX calls, timers, animations. jQuery Deferred gives you a structured way to run code when those tasks succeed, fail, or update progress. This hub links to 18 Deferred method tutorials.

01

Deferred()

Create objects

02

done / fail

Success & error

03

always

Cleanup

04

then

Chain steps

05

promise

Read-only view

06

18 guides

Full index

Introduction

When a task takes time — fetching data, waiting for an animation, reading a file — you cannot block the browser. Instead, you register callbacks that run later. jQuery Deferred is the utility that queues those callbacks and fires them when you call resolve() or reject().

What Is jQuery Deferred?

A Deferred object represents the eventual outcome of an asynchronous operation. It can be pending (still running), resolved (success), or rejected (failure). You attach handlers before settlement, and jQuery runs them in order when the state changes.

💡
Beginner Tip

Think of Deferred like a ticket counter: you line up callbacks (done, fail) first, then the clerk calls resolve or reject when your order is ready.

Key Features

  • Callback attachment — Register multiple handlers for success, failure, progress, or either outcome.
  • Promise integration — Expose a read-only promise() so callers cannot accidentally resolve your task.
  • Chaining — Use then() to pipe results through a pipeline, similar to native Promises.
  • AJAX built-in$.ajax() returns a jqXHR that already behaves like a Deferred.

📝 Syntax

Create a Deferred, attach handlers, and settle it:

jQuery
const dfd = $.Deferred();

dfd.done(function (data) {
  console.log("Success:", data);
}).fail(function (err) {
  console.error("Failed:", err);
}).always(function () {
  console.log("Cleanup runs either way");
});

// Later, when async work finishes:
dfd.resolve("Hello from Deferred");

Method groups

GroupExamplesPurpose
Factory$.Deferred()Create a new Deferred object
Handlersdone(), fail(), always()Register callbacks
Settlementresolve(), reject()Finish the async task
Chainingthen(), catch()Pipeline transforms and errors
Progressprogress(), notify()Interim status updates
Statusstate(), promise()Inspect or expose read-only access

⚡ Quick Reference

GoalMethod
Create a Deferred$.Deferred()
On successdfd.done(fn)
On failuredfd.fail(fn)
Cleanup either waydfd.always(fn)
Chain stepsdfd.then(doneFn, failFn)
Mark successdfd.resolve(value)
Mark failuredfd.reject(reason)
Check status (jQuery 3+)dfd.state() → pending | resolved | rejected
Share read-only accessdfd.promise()

When to Use Deferred

  • Custom async APIs — Wrap setTimeout, third-party SDKs, or Web APIs in a Deferred your app can consume uniformly.
  • AJAX requests — Chain .done() / .fail() on $.ajax() without nested callbacks.
  • Animation sequences — Coordinate code that runs when effects complete or fail.
  • Module boundaries — Return promise() from a module so internals stay private.
  • Progress UI — Use notify() and progress() for upload bars or multi-step wizards.

👀 Deferred Lifecycle

A Deferred moves through three states:

pending → resolve() → resolved → done() + always() run pending → reject() → rejected → fail() + always() run pending → notify() → still pending → progress() runs

Deferred Method Tutorial Index

Search by method name or browse by category. Each tutorial includes syntax, five try-it examples, and FAQs.

Getting Started

4 tutorials

Create Deferreds and attach the core success/failure listeners.

MethodDescriptionTutorial
jQuery.Deferred()Factory that creates a new Deferred object for custom async workflows.Open
done()Register a callback that runs when the Deferred resolves successfully.Open
fail()Register a callback that runs when the Deferred is rejected.Open
promise()Return a read-only promise so callers cannot resolve or reject.Open

Handlers & Chaining

5 tutorials

Register callbacks, chain transforms, and handle errors in pipelines.

MethodDescriptionTutorial
always()Register a callback that runs after resolve or reject — ideal for cleanup.Open
catch()Handle rejection at the end of a promise chain (like Promise.catch).Open
then()Chain success and failure handlers; return values flow to the next step.Open
pipe()Legacy filter/chain API — deprecated in jQuery 3+; use then() instead.Open
progress()Listen for interim progress updates from notify() or notifyWith().Open

Progress

2 tutorials

Report interim status before final resolve or reject.

MethodDescriptionTutorial
notify()Send a progress update while the Deferred is still pending.Open
notifyWith()Send progress with a custom this context and argument array.Open

State & Settlement

7 tutorials

Resolve, reject, inspect status, and bind context with With-methods.

MethodDescriptionTutorial
resolve()Settle the Deferred as successful and pass results to done() handlers.Open
resolveWith()Resolve with a custom this context and arguments in an array.Open
reject()Settle the Deferred as failed and pass reasons to fail() handlers.Open
rejectWith()Reject with a custom this context and arguments in an array.Open
state()Return "pending", "resolved", or "rejected" — preferred status check in jQuery 3+.Open
isResolved()Return true if the Deferred resolved (deprecated — prefer state()).Open
isRejected()Return true if the Deferred rejected (deprecated — prefer state()).Open

Examples Gallery

Include jQuery 3.7+ and open DevTools Console (F12) to run each snippet.

📚 Create & Listen

Build a Deferred and settle it manually.

Example 1 — Create and Resolve a Deferred

Simulate async work with setTimeout, then resolve with a result.

jQuery
function fetchGreeting() {
  const dfd = $.Deferred();

  setTimeout(function () {
    dfd.resolve("Hello, Deferred!");
  }, 500);

  return dfd.promise();
}

fetchGreeting().done(function (msg) {
  console.log(msg);
});

How It Works

The factory creates a Deferred; you return promise() so callers cannot call resolve themselves. Settlement happens inside your async function.

Example 2 — done(), fail(), and always()

Classic AJAX-style handlers for success, error, and shared cleanup.

jQuery
function loadData(shouldFail) {
  const dfd = $.Deferred();
  setTimeout(function () {
    if (shouldFail) {
      dfd.reject("Network error");
    } else {
      dfd.resolve({ id: 1, name: "Ada" });
    }
  }, 300);
  return dfd.promise();
}

loadData(false)
  .done(function (data) { console.log("Loaded:", data.name); })
  .fail(function (err) { console.error(err); })
  .always(function () { console.log("Request finished"); });
done() Tutorial

How It Works

always() runs after either branch — perfect for hiding loading spinners. Pass true to loadData to see the fail path instead.

📈 Chain & Encapsulate

Pipeline values and hide settlement from consumers.

Example 3 — Chain with then()

Transform resolved values through a pipeline — similar to native Promises.

jQuery
$.Deferred()
  .resolve(10)
  .then(function (n) { return n * 2; })
  .then(function (n) { return "Result: " + n; })
  .done(function (msg) { console.log(msg); });
then() Tutorial

How It Works

Each then() callback can return a new value that flows to the next step. Use the second argument or catch() for error handling in longer chains.

Example 4 — Expose promise() Only

Keep resolve/reject private inside a module; return a read-only promise.

jQuery
const Timer = (function () {
  const dfd = $.Deferred();

  setTimeout(function () {
    dfd.resolve("Timer done");
  }, 400);

  // Public API — no resolve/reject exposed
  return {
    onComplete: dfd.promise()
  };
})();

Timer.onComplete.done(function (msg) {
  console.log(msg);
});

// Timer.onComplete.resolve("hack"); // undefined — safe!

How It Works

promise() strips settlement methods. External code can listen but cannot change the outcome — a simple encapsulation pattern.

Example 5 — Inspect with state()

Check whether a Deferred is still pending or has settled (jQuery 3+).

jQuery
const dfd = $.Deferred();

console.log("Before:", dfd.state()); // pending

dfd.resolve("OK");
console.log("After resolve:", dfd.state()); // resolved

const dfd2 = $.Deferred();
dfd2.reject("Oops");
console.log("After reject:", dfd2.state()); // rejected
state() Tutorial

How It Works

state() replaces deprecated isResolved() / isRejected() with one clear string. A Deferred can only settle once — subsequent resolve/reject calls are ignored.

🚀 Use Cases

  • AJAX requests — Handle server responses and errors without deeply nested callbacks.
  • Animation sequences — Run the next step when .fadeOut() or custom effects complete.
  • Complex workflows — Coordinate tasks that depend on other async operations finishing first.
  • Plugin APIs — Let plugin users attach callbacks while you control when work completes.

🌟 Advantages

  • Cleaner organization — Separate success, failure, and cleanup instead of one giant callback.
  • Better error handling — Route failures to fail() or catch() consistently.
  • Promise compatibility — Integrates with jQuery AJAX and patterns familiar from native Promises.
  • Progress support — Report interim status with notify() — something basic callbacks lack.

💬 Usage Tips

  • Register handlers first — Attach done / fail before calling resolve or handlers may miss synchronous settlement.
  • Return promise() — From public functions, not the raw Deferred.
  • Prefer state() — Over deprecated status helpers in new code.
  • Use then() for pipelines — Replace deprecated pipe() in jQuery 3+ projects.
  • Search this index — Jump to any of 18 method pages above.

⚠️ Common Pitfalls

  • Double settlement — Only the first resolve or reject counts; later calls are ignored silently.
  • Leaking the Deferred — Returning the Deferred lets callers resolve your task — use promise().
  • Mixing paradigms — Native Promises and jQuery Deferred are similar but not identical; test mixed chains carefully.
  • Deprecated pipe() — Still documented for legacy code; choose then() for new tutorials and projects.
  • Forgetting always() — UI cleanup belongs in always(), not duplicated in both done and fail.

🧠 How Deferred Works

1

Create

$.Deferred() starts in the pending state with empty callback queues.

Factory
2

Register handlers

done, fail, always, and progress queue callbacks for later.

Listen
3

Settle

resolve or reject locks the state and drains the matching queues.

Settle
=

Responsive async code

Callbacks run in order, UI stays unblocked, and errors have a clear path.

Browser Support

jQuery Deferred ships with jQuery 1.5+ and is fully supported in jQuery 3.7.x. Methods like state() and catch() align with jQuery 3+. For greenfield projects, also consider native Promise — but Deferred remains essential when using jQuery AJAX and legacy plugins.

jQuery 1.5+

Deferred & Promise API

Available wherever jQuery runs — all modern browsers and IE 9+ with a supported jQuery build. Match your jQuery version to project requirements.

100% With jQuery
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
Deferred methods Universal

Bottom line: Safe for jQuery-based apps. Prefer state() and then() in jQuery 3+ code; treat pipe() as legacy.

🎉 Conclusion

jQuery Deferred is a powerful tool for managing asynchronous tasks — from AJAX to animations to custom APIs. Start with $.Deferred(), done(), and resolve(), then explore chaining and progress as you grow.

Use the searchable index to open all 18 tutorials — each includes try-it labs and FAQs.

💡 Best Practices

✅ Do

  • Return promise() from public APIs
  • Use always() for shared cleanup
  • Check status with state()
  • Chain multi-step work with then()
  • Register handlers before settling

❌ Don’t

  • Expose the raw Deferred to callers
  • Call resolve and reject both
  • Duplicate cleanup in done and fail
  • Use pipe() in new jQuery 3 code
  • Memorize all 18 names at once

Key Takeaways

Knowledge Unlocked

Five things to remember about Deferred

Your gateway to 18 method tutorials.

5
Core concepts
02

done / fail

Success & error

Handlers
03

always

Either outcome

Cleanup
04

then()

Chain values

Pipeline
18 05

Index

Search all

Ref

❓ Frequently Asked Questions

A Deferred is a jQuery object that represents an asynchronous task. You register callbacks for success (done), failure (fail), cleanup (always), or progress, then settle it later with resolve() or reject(). It powers $.ajax() and custom async APIs.
A Deferred is read-write — you can resolve, reject, and notify. promise() returns a read-only Promise that consumers can listen to but cannot settle. Share the promise with callers; keep the Deferred private inside your module.
Both work. done() and fail() are explicit and great for beginners. then() chains transforms and errors in one pipeline — similar to native Promises. Prefer then() for multi-step pipelines; use done/fail/always for simple AJAX-style handlers.
In jQuery 3+, call state() — it returns "pending", "resolved", or "rejected". Older isResolved() and isRejected() still work but are deprecated.
Yes. jqXHR objects returned by $.ajax() implement the Deferred interface, so you can chain .done(), .fail(), .always(), and .then() directly on AJAX calls.
Read the overview, try the five examples, then open jQuery.Deferred() or always() from Getting Started. Use the search box to jump to any of the 18 method tutorials.
Did you know?

Every $.ajax() call returns a jqXHR object that is also a Promise-like Deferred. That is why $.get("/api/users").done(render).fail(showError) works without you creating a Deferred manually.

Start with always()

Learn how to run cleanup code whether an async task succeeds or fails.

always() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

10 people found this page helpful