jQuery Deferred done() Method

Beginner
6 min read
Updated: Oct 2026
4 examples
Live preview

What Is done()?

deferred.done(doneCallbacks) adds handlers that run when a Deferred is resolved (success). Available since jQuery 1.5. It returns the Deferred so you can chain more methods.

Remember
dfd.done(fn)
dfd.done(fn1, fn2)
dfd.done([fn1, fn2], fn3)

resolve("ok")  → done handlers run with "ok"
reject(...)    → done does NOT run

$.get(url).done(fn)  // jqXHR success
NeedUse
On successdfd.done(fn)
On failuredfd.fail(fn)
Either outcomedfd.always(fn)

How to Use done()

Create or receive a Deferred/Promise, attach done, then resolve (or wait for AJAX).

  1. Get a Deferred (e.g. $.Deferred()) or a jqXHR from $.ajax / $.get.
  2. Call .done(function (value) { ... }) — pass a function or an array of functions.
  3. When success happens, call resolve(value) (or let AJAX succeed).
  4. Handlers run in order with the resolve arguments; chain fail / always as needed.
PieceRequired?Role
Deferred / jqXHRYesObject that can resolve
doneCallbacksYesFunction or array of functions
Return value—Same Deferred (chainable)

Pseudocode

Pseudocode
function done(deferred, callbacks):
    queue = flatten(callbacks)   // functions and arrays
    add each callback to success list

    when deferred.resolve(args...):
        for each fn in success list (in order):
            fn(args...)

    return deferred              // chainable

Cheat Sheet

Keep these facts handy while wiring success handlers.

TopicDetail
Syntaxdeferred.done(doneCallbacks [, doneCallbacks ])
SincejQuery 1.5
Runs whenDeferred is resolved
ArgumentsSame values passed to resolve / resolveWith
Multiple handlersFunctions or arrays; order preserved
Late attachIf already resolved → runs immediately
ReturnsThe Deferred (chainable)

Live Preview

Pick a scenario and see how done() behaves on resolve.

Browser demo of deferred.done() — same ideas as the examples below.

Result
done: Request successful

jQuery Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Basic Success Handler

Attach done(), then resolve() with a message.

jQuery
var dfd = $.Deferred();

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

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

How It Works

  1. Create. $.Deferred() starts in the pending state.
  2. Register. done(fn) queues the success callback.
  3. Resolve. resolve("Request successful") settles as success.
  4. Run. The handler receives that string and logs it.

Example 2 — Multiple Handlers

Pass functions or arrays; they run in registration order (per the API docs).

jQuery
var dfd = $.Deferred();
var lines = [];

function fn1() { lines.push("1"); }
function fn2() { lines.push("2"); }
function fn3(n) { lines.push(n + " 3 " + n); }

dfd.done([fn1, fn2], fn3).done(function (n) {
  lines.push(n + " we're done.");
});

dfd.resolve("and");
console.log(lines.join(" "));
// 1 2 and 3 and and we're done.
Try It Yourself

How It Works

  1. Arrays allowed. [fn1, fn2] adds both callbacks in order.
  2. Extra args. fn3 and the chained done also receive "and".
  3. Order. Handlers fire in the order they were added.
  4. Chain. done() returns the Deferred, so another .done() works.

Example 3 — Multiple Resolve Arguments

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

jQuery
var dfd = $.Deferred();

dfd.done(function (status, body, type) {
  console.log(status);  // 200
  console.log(body);    // { ok: true }
  console.log(type);    // application/json
});

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

How It Works

  1. Multi-arg resolve. jQuery forwards every argument to each done callback.
  2. Parameter list. Match them left-to-right: status, body, type.
  3. Use case. Mimics patterns where status and payload travel together.
  4. Tip. Prefer one object argument in new code when possible — clearer to read.

Example 4 — Late Registration

If the Deferred is already resolved, a new done() still runs right away.

jQuery
var dfd = $.Deferred();

dfd.resolve("already settled");

dfd.done(function (value) {
  console.log("done (late): " + value);
});
// done (late): already settled
Try It Yourself

How It Works

  1. Settle first. resolve happens before any handler is attached.
  2. Attach late. done(fn) sees the Deferred is already resolved.
  3. Immediate call. jQuery invokes fn with the stored resolve value.
  4. Why it matters. Modules can attach listeners safely at different times.

Edge Cases & Pitfalls

Check these before relying on done() alone.

path

No reject coverage

done() never runs on failure. Always pair with fail(), catch(), or a rejection branch on then().

chain

done vs then chaining

done() returns the same Deferred. then() returns a new Promise — use then when you need to transform values down a chain.

order

Handler order is fixed

Callbacks run in registration order. Do not assume parallel execution — keep side effects safe to run sequentially.

once

Settled only once

A Deferred resolves or rejects once. Extra resolve calls are ignored; late done handlers still see the first result.

Browser Support

deferred.done() has shipped since jQuery 1.5 and works in all modern browsers with jQuery loaded. It is part of the Deferred Object API (also used by jqXHR).

✓ jQuery 1.5+

deferred.done()

Supported everywhere jQuery Deferred runs in the browser. Use it for success callbacks on Deferred and AJAX objects.

100% Browser support
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
done() Excellent

Bottom line: Call dfd.done(fn) for success. Pair with fail() for errors. Works on Deferred and jqXHR since jQuery 1.5.

Performance Notes

ApproachCostBest for
dfd.done(fn)O(k) handlersSuccess-only side effects
dfd.then(fn)O(k) + new PromiseValue transforms / chains
dfd.always(fn)O(k)Shared cleanup

Handler cost is usually tiny compared with the async work (network, timers). Prefer clear success/error separation over micro-optimizing callback count.

Key Takeaways

  • Role: success callbacks when a Deferred resolves.
  • Multi: pass functions or arrays; order is preserved.
  • Pair: use fail() / always() for errors and cleanup.
  • Late attach: already resolved → handler runs immediately.

One line: dfd.done(fn) runs on resolve only — queue success work, and pair with fail() for the error path.

Frequently Asked Questions

done() registers one or more callbacks that run when the Deferred is resolved (success). Handlers receive the values passed to resolve() or resolveWith(), in registration order.
done() runs only on resolve. fail() runs only on reject. Pair them (or use then with two callbacks) so you cover both outcomes.
For success only, similar: then(onFulfilled) also runs on resolve. done() is success-only and does not accept a rejection handler. then() can take both fulfilled and rejected callbacks (jQuery 3+).
Yes. Pass functions or arrays of functions. Callbacks run in the order they were added. You can also chain .done().done().
Yes. If the Deferred is already resolved, new done() handlers fire immediately with the resolved values.
Yes. jqXHR objects support .done(), .fail(), and .always() — the classic jQuery success-handler pattern.

Next: fail()

Learn how to attach rejection handlers when a Deferred fails.

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.

9 people found this page helpful