jQuery Deferred done() Method

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Success handlers

What You’ll Learn

The done() method registers a success callback on a jQuery Deferred. It runs when the operation resolves — with data from resolve(), an AJAX response, or a completed animation. This tutorial covers syntax, five examples, comparisons with fail() and then(), and best practices.

01

Syntax

dfd.done(fn)

02

On resolve

Success only

03

vs fail()

Error path separate

04

AJAX

$.ajax().done()

05

Multiple

Queue handlers

06

Since 1.5

Core Deferred API

Introduction

Async tasks usually end in one of two ways: success or failure. jQuery’s done() method is dedicated to the success path. When a Deferred resolves — because an AJAX call returned data, a timer finished, or you called resolve() manually — every registered done() callback runs with the result.

Keep outcome-specific work in done(): render UI, parse JSON, trigger follow-up requests. Pair it with fail() or catch() for errors and always() for shared cleanup.

Understanding the done() Method

done() is part of jQuery’s Deferred Object API (since jQuery 1.5). Calling deferred.done(callback) adds your function to a success queue. When the Deferred enters the resolved state, jQuery invokes each callback in order, passing the values from resolve().

done() does not run on rejection. If the Deferred fails, only fail(), catch(), and always() handlers execute (plus then() rejection branches).

💡
Beginner Tip

If you register done() after the Deferred already resolved, jQuery still calls your handler immediately — handy when different modules attach listeners at different times.

📝 Syntax

General form of deferred.done:

jQuery
deferred.done( doneCallback [, doneCallback ] )

Parameters

  • doneCallback — function executed when the Deferred resolves. Receives resolve arguments (often one data object, or multiple values from resolve(a, b, c)).

Return value

  • Returns the same Deferred object for chaining fail(), always(), or another done().

AJAX example

jQuery
$.ajax({
  url: "/api/profile",
  method: "GET"
}).done(function (response) {
  console.log("Request successful:", response);
});

⚡ Quick Reference

GoalCode
Success handlerdfd.done(fn)
Error handlerdfd.fail(fn)
Either outcome cleanupdfd.always(fn)
Promise-style successdfd.then(fn) (jQuery 3+)
Pass multiple valuesdfd.resolve(a, b, c)

📋 done() vs fail() vs then()

Each method listens for a different Deferred outcome.

done()
on resolve

Success callbacks

fail()
on reject

Error callbacks

then()
both paths

Promises/A+ style

always()
on either

Shared cleanup

Examples Gallery

Each example demonstrates success handling with jQuery Deferred. Use DevTools or the Try-it links to run them.

📚 Getting Started

Attach done() and resolve with a success value.

Example 1 — Basic Success Handler

Register done(), then call resolve() with a message.

jQuery
const dfd = $.Deferred();

dfd.done(function (value) {
  console.log("done:", value);
});

dfd.resolve("Request successful");
Try It Yourself

How It Works

resolve() settles the Deferred as success. Queued done() handlers run synchronously in this example because no real async delay exists.

Example 2 — AJAX-Style Success Processing

Simulate a successful fetch and process the response object in done().

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

  setTimeout(function () {
    dfd.resolve({ name: "Alex", role: "Editor" });
  }, 500);

  return dfd.done(function (response) {
    console.log("Request successful");
    console.log(response.name, response.role);
  });
}
Try It Yourself

How It Works

This mirrors $.ajax(...).done(fn): the success handler receives parsed data and updates the UI or application state.

📈 Practical Patterns

Multiple listeners, resolve arguments, and late registration.

Example 3 — Multiple done() Handlers

Split success work across focused callbacks — logging, UI, and analytics.

jQuery
const dfd = $.Deferred();

dfd.done(function (data) {
  console.log("Log:", data);
});

dfd.done(function (data) {
  $("#status").text("Loaded " + data);
});

dfd.done(function (data) {
  trackEvent("load", data);
});

dfd.resolve("order-42");
Try It Yourself

How It Works

jQuery calls every done() handler in registration order with the same resolve arguments — similar to adding multiple event listeners for one success signal.

Example 4 — Multiple Resolve Arguments

resolve() can pass several values; done() receives them as separate parameters.

jQuery
const dfd = $.Deferred();

dfd.done(function (status, body, contentType) {
  console.log(status, body, contentType);
});

dfd.resolve(200, "{ ok: true }", "application/json");
Try It Yourself

How It Works

jQuery forwards all arguments from resolve() to done() callbacks — useful when mimicking HTTP status, body, and headers separately.

Example 5 — Register done() After Resolve

Handlers added after settlement still run if the Deferred already resolved.

jQuery
const dfd = $.Deferred();

dfd.resolve("already settled");

dfd.done(function (value) {
  console.log("done (registered late):", value);
});
Try It Yourself

How It Works

Resolved Deferreds remember their value. Late done() handlers execute immediately — rejected Deferreds behave the same way for fail().

🚀 Use Cases

  • AJAX requests — update the DOM or store server data when the response succeeds.
  • Animation effects — run follow-up code when .fadeOut() or custom Deferred-based animations complete.
  • Promise chains — combine with then() to transform success values step by step.
  • Timeouts — execute success logic when an operation finishes within an expected window.
  • Modular listeners — let different parts of the app attach their own done() handlers to the same Deferred.

🧠 How done() Runs on Resolve

1

Register

dfd.done(fn) queues your callback while the Deferred is pending or already resolved.

Queue
2

Resolve

Async work completes; resolve(value) moves state to resolved.

Success
3

Callbacks fire

Each done handler runs in order with resolve arguments.

Execute
=

UI updated

Success path complete — optionally chain always() for shared cleanup.

📝 Notes

  • done() never runs when the Deferred is rejected — use fail() instead.
  • Returning a value from done() does not change the chain; use then() to transform and pass values forward.
  • Prefer validating data inside done() before rendering untrusted server responses.
  • On jQuery 3+, then(onFulfilled) is often used in new code; done() remains widely used in legacy jQuery AJAX.
  • Always add error handling — success-only chains leave users stuck when requests fail.

Browser Support

deferred.done() has been available since jQuery 1.5 alongside the Deferred API. It works in every browser your jQuery build supports.

jQuery 1.5+

jQuery Deferred.done()

Supported in jQuery 1.5+, 2.x, and 3.x. Behavior is consistent across browsers because jQuery implements the callback queue internally.

100% With jQuery loaded
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.done() Universal

Bottom line: Safe in any project using jQuery Deferred or jqXHR. For greenfield code without jQuery, native Promise .then() is the modern equivalent for success handlers.

🎉 Conclusion

The deferred.done() method is jQuery’s dedicated success handler. Register callbacks before or after resolve(), process AJAX responses, and split work across multiple focused listeners — then pair with fail() for a complete async story.

Practice the five examples above, then continue to fail() to handle the rejection path on the same Deferred chain.

💡 Best Practices

✅ Do

  • Keep done() callbacks focused on success logic
  • Validate and transform response data before use
  • Pair with fail() or catch() for errors
  • Use always() for spinners and button re-enable
  • Test success paths with realistic sample data

❌ Don’t

  • Put error handling only in done()
  • Assume done() runs on reject
  • Return transformed values expecting chain updates — use then()
  • Trust server data without validation
  • Forget late listeners — they still run after resolve

Key Takeaways

Knowledge Unlocked

Five things to remember about done()

Your success path for jQuery async work.

5
Core concepts
02

Resolve

Success only

Trigger
🔗 03

Queue

Multiple fns

Order
📦 04

Args

From resolve()

Data
05

Late fn

Still runs

Tip

❓ Frequently Asked Questions

done() registers a callback that runs when the Deferred is resolved (success). The handler receives whatever values were passed to resolve() or resolveWith().
done() runs only on resolve. fail() runs only on reject. They are mutually exclusive for a given settlement — pair done() with fail() or catch() to cover both outcomes.
Similar for success: then(onFulfilled) runs when resolved. done() is jQuery's legacy name and only handles success — it does not accept a rejection handler. then() accepts both fulfilled and rejected callbacks (jQuery 3+).
Yes. Each done callback is queued and executed in registration order when the Deferred resolves.
Yes. If the Deferred is already resolved, new done() handlers fire immediately with the resolved values.
Yes. jqXHR objects support .done(), .fail(), and .always() — a common pattern for processing successful HTTP responses.
Did you know?

Before jQuery unified callbacks with Deferred in 1.5, $.ajax() used separate success, error, and complete options. done(), fail(), and always() replaced that pattern with chainable methods on the same object.

Continue to fail()

Learn how jQuery handles rejected Deferreds on the error path.

fail() 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.

6 people found this page helpful