jQuery Deferred pipe() Method

Beginner
8 min read
Updated: Oct 2026
5 examples
Live preview

What Is pipe()?

deferred.pipe() filters and/or chains a Deferred. Optional doneFilter, failFilter, and progressFilter map resolve, reject, and progress values. It returns a new Promise (since jQuery 1.6; progress filter since 1.7).

Remember
deferred.pipe(doneFilter [, failFilter [, progressFilter]])

doneFilter(value)     → next success value or Promise
failFilter(reason)    → next reject value (or Promise)
progressFilter(n)     → next progress value

null / omitted filter → pass status & values through
prefer then() in new code
NeedUse
Transform & chain (modern)dfd.then(fn)
Side effect onlydfd.done(fn)
Legacy transform chaindfd.pipe(fn) (1.6–3.x)

How to Use pipe()

Create a Deferred, pipe filters, then resolve (or reject) the source.

  1. Build a Deferred (or use a promise from AJAX / helpers).
  2. Call pipe(doneFilter) — optionally add fail and progress filters.
  3. Return a value or another promise from the filter.
  4. Attach done() / fail() (or then()) on the piped promise.
  5. In new code, write then() instead of pipe().
PieceRequired?Role
doneFilterOptionalRuns on resolve; return value feeds the chain
failFilterOptionalRuns on reject; maps the failure path
progressFilterOptionalRuns on notify() (since 1.7)
Return—New Promise representing the filtered chain

Pseudocode

Pseudocode
source = Deferred
piped  = new Promise

when source resolves with value:
    if doneFilter exists:
        out = doneFilter(value)
        if out is a Promise: wait, then settle piped like out
        else: resolve piped with out
    else:
        resolve piped with value

when source rejects with reason:
    // failFilter maps reason; plain return still rejects piped
    // (return a resolved Deferred to recover)

prefer: source.then(doneFilter, failFilter)

Cheat Sheet

Keep these facts handy while reading legacy chains.

TopicDetail
Syntaxdeferred.pipe(done [, fail [, progress]])
Transform successdfd.pipe(function (v) { return v * 2; })
Map rejectdfd.pipe(null, failFn)
Chain asyncReturn another Deferred / Promise from the filter
vs done()done ignores return values; pipe does not
Modern swapdfd.then(onFulfilled, onRejected)
StatusDeprecated since jQuery 1.8

Live Preview

Resolve a Deferred with 5, then see what pipe() (or then()) produces.

Browser demo of deferred.pipe — same idea as the examples below.

Result
defer.resolve(5)
pipe(n → n * 2)
→ 10

/* doneFilter transforms the resolve value */

jQuery Examples

Short, copy-ready snippets. Open the browser console, or use Try It Yourself for a live editor.

Example 1 — Transform a Resolved Value

Multiply the resolve value in doneFilter; the piped promise gets the new number.

jQuery
var defer = $.Deferred();
var filtered = defer.pipe(function (value) {
  return value * 2;
});

defer.resolve(5);

filtered.done(function (value) {
  console.log(value);  // 10
});
Try It Yourself

How It Works

  1. Create source and pipe. filtered is a new promise wired to the filter.
  2. Resolve with 5. jQuery calls doneFilter(5).
  3. Return 10. That number becomes the resolve value of filtered.
  4. Read the result. done() on the piped promise logs 10.

Example 2 — Filter a Reject Value

Pass null for doneFilter and map the rejection reason. A plain return still rejects.

jQuery
var defer = $.Deferred();
var filtered = defer.pipe(null, function (value) {
  return value * 3;
});

defer.reject(6);

filtered.fail(function (value) {
  console.log(value);  // 18
});
Try It Yourself

How It Works

  1. Skip success. First argument is null — only the fail path is filtered.
  2. Reject with 6. failFilter receives 6.
  3. Return 18. The piped promise rejects with 18 (not a recovery to success).
  4. Handle with fail. Attach .fail() to read the mapped reason.

Example 3 — Chain Async Tasks

Return another promise from doneFilter so the chain waits for the next step.

jQuery
function fetchUserId() {
  var d = $.Deferred();
  setTimeout(function () { d.resolve({ id: 42 }); }, 200);
  return d.promise();
}

function fetchProfile(userId) {
  var d = $.Deferred();
  setTimeout(function () {
    d.resolve({ userId: userId, name: "Alex" });
  }, 200);
  return d.promise();
}

fetchUserId().pipe(function (data) {
  return fetchProfile(data.id);
}).done(function (profile) {
  console.log(profile.name);  // Alex
});
Try It Yourself

How It Works

  1. First task. fetchUserId() resolves with { id: 42 }.
  2. Return a promise. The filter starts fetchProfile(42) and returns it.
  3. Wait. The piped chain pauses until that second promise resolves.
  4. Final done. profile.name is "Alex".

Example 4 — Progress Filter

Map progress values from notify() before they reach progress() handlers.

jQuery
var defer = $.Deferred();
var filtered = defer.pipe(null, null, function (n) {
  return n + "%";
});

filtered.progress(function (label) {
  console.log(label);  // 50%
});

defer.notify(50);
defer.resolve("done");
Try It Yourself

How It Works

  1. Pass nulls. Skip done/fail filters; only progressFilter runs.
  2. Notify 50. The filter receives 50 and returns "50%".
  3. Progress handler. filtered.progress logs the mapped label.
  4. Resolve after. Progress is independent of the final resolve.

Example 5 — pipe() vs then()

Same transform — modern jQuery code uses then().

jQuery
$.Deferred().resolve(3).pipe(function (n) {
  return n + 7;
}).done(function (legacy) {
  console.log("pipe:", legacy);  // 10
});

$.Deferred().resolve(3).then(function (n) {
  return n + 7;
}).then(function (modern) {
  console.log("then:", modern);  // 10
});
Try It Yourself

How It Works

  1. Legacy path. pipe adds 7 → 10 via done().
  2. Modern path. then does the same transform and chains another then.
  3. Same result. Both print 10 for this simple case.
  4. Rule. New code: write then(); keep pipe() for legacy only.

Edge Cases & Pitfalls

Check these before relying on pipe() in real projects.

deprecated

Deprecated since 1.8

Official docs mark pipe() deprecated. Prefer then() for all new chains.

fail

Plain failFilter return still rejects

Returning a number/string from failFilter maps the reason but keeps the piped promise rejected. Return a resolved Deferred to recover to success.

done

done() does not transform

Return values from done() / fail() are ignored. Use pipe() or then() when the next step needs a new value.

then

then() rejection recovery differs

In jQuery 3+, returning a plain value from a then rejection handler fulfills the next promise (Promises/A+). pipe failFilter plain returns still reject — do not assume they match.

Browser Support

deferred.pipe() needs jQuery 1.6+ (progress filter since 1.7). It still works in jQuery 3.x but is deprecated since 1.8 — prefer then().

✓ jQuery 1.6+ · Deprecated 1.8

deferred.pipe()

Works in Chrome, Firefox, Safari, and Edge when jQuery 1.6+ is loaded. Use deferred.then() for new projects.

Legacy Use then()
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
pipe() Deprecated

Bottom line: Replace .pipe(fn) with .then(fn) in new code. Keep pipe() only while maintaining older chains.

Performance Notes

ApproachCostBest for
pipe(fn)One extra promise + filter callLegacy transform chains
then(fn)Same order of costAll new jQuery 3+ code
done(fn)Cheapest callbackSide effects with no transform

Pipeline cost is dominated by your async work (timers, AJAX), not by pipe vs then. Choose then() for API clarity and future maintenance, not micro-benchmarks.

Key Takeaways

  • Role: filter and chain Deferred resolve / reject / progress values.
  • Return matters: values and promises from filters feed the next link.
  • Migrate: use then() — pipe() is deprecated since 1.8.
  • failFilter: plain return still rejects; return a resolved Deferred to recover.

One line: pipe() transforms Deferred chains — learn it for legacy code, write then() for new work.

Frequently Asked Questions

pipe() returns a new Promise that filters a Deferred’s resolve, reject, and (optionally) progress values. doneFilter runs on resolve; failFilter on reject; progressFilter on notify. Return a value or another promise to feed the next step.
Yes. As of jQuery 1.8, deferred.pipe() is deprecated. Use deferred.then() instead — it replaces pipe() and follows Promises/A+ semantics in jQuery 3+.
done() only registers a side-effect callback — its return value is ignored. pipe() (and then()) use the filter’s return value as the next link’s input.
The piped promise stays rejected, but with the new value. Official pattern: map the reason, then attach .fail(). To recover into success, return a resolved Deferred from failFilter.
Yes. Return a Deferred or Promise from doneFilter; the piped chain waits until that promise settles, then continues with its value.
No. Prefer then(onFulfilled, onRejected) in jQuery 3+. Keep pipe() only when reading or maintaining legacy jQuery 1.x/2.x chains.

Next: deferred.progress()

Learn how to register handlers for notify() progress events.

progress() 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