jQuery Deferred pipe() Method

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Chain & transform

What You’ll Learn

The pipe() method filters and transforms values in a jQuery Deferred chain. Return a new value or another promise from doneFilter to pass results to the next step. This tutorial covers syntax, five examples, comparisons with done() and then(), and why pipe() is deprecated in jQuery 3+.

01

Syntax

pipe(done, fail, prog)

02

doneFilter

Transform success

03

Return value

Feeds next link

04

New promise

Chain async steps

05

vs then()

Modern replacement

06

Since 1.7

Deprecated in 3.0

Introduction

Async workflows often need more than a single callback. After one task finishes, you may transform its result, start another request, or map errors before the UI updates. jQuery’s pipe() method builds that pipeline — each filter function receives the previous outcome and returns what the next link should receive.

In jQuery 3+, then() replaces pipe() with Promises/A+-compatible behavior. Understanding pipe() still helps when reading legacy code and when migrating chains to then().

Understanding the pipe() Method

pipe() returns a new promise-like object wired to filter callbacks. When the source Deferred resolves, jQuery calls doneFilter with the resolved values. Whatever the filter returns — a plain value, a new Deferred, or a thrown error — determines how the piped chain continues.

Optional failFilter handles rejections; optional progressFilter handles notify() progress events. Unlike done(), which ignores return values, pipe() is designed for value transformation.

💡
Beginner Tip

The reference AJAX examples use placeholder URLs like example.com/data — they illustrate chaining shape, not runnable endpoints. Our examples use $.Deferred() simulations you can run in Try-it labs without a server.

📝 Syntax

General form of deferred.pipe:

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

Parameters

  • doneFilter — runs on resolve; return value or promise becomes the next chain input.
  • failFilter — optional; runs on reject for error mapping or recovery.
  • progressFilter — optional; runs on progress (notify()) events.

Return value

  • Returns a new promise object representing the filtered chain — attach further pipe(), then(), done(), or fail() to it.

Modern equivalent (jQuery 3+)

jQuery
// Legacy
dfd.pipe(function (value) {
  return value * 2;
});

// Preferred in jQuery 3+
dfd.then(function (value) {
  return value * 2;
});

⚡ Quick Reference

GoalCode
Transform resolved valuedfd.pipe(fn)
Chain another async taskdfd.pipe(function (v) { return nextTask(v); })
Map rejectiondfd.pipe(null, failFn)
Side effect only (no transform)dfd.done(fn)
Modern replacementdfd.then(onFulfilled, onRejected)

📋 pipe() vs done() vs then()

Three chaining tools — transform, side-effect, or modern promise style.

pipe()
transform

Return value matters

done()
side effect

Return ignored

then()
Promises/A+

jQuery 3+ preferred

Status
deprecated

Since jQuery 3.0

Examples Gallery

Each example shows how pipe() transforms or chains Deferred results. Use the Try-it links to run them interactively.

📚 Getting Started

Multiply a resolved number through a doneFilter.

Example 1 — Transform a Resolved Value

The filter receives the resolve value and returns a new one for the next step.

jQuery
const dfd = $.Deferred();

dfd.resolve(5);

dfd.pipe(function (n) {
  return n * 10;
}).done(function (result) {
  console.log(result);  // 50
});
Try It Yourself

How It Works

resolve(5) triggers the filter with 5. Returning 50 from the filter becomes the value passed to the final done() handler.

Example 2 — Sequential Async Tasks

Pass the first task’s result into a second simulated fetch via pipe().

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

function fetchProfile(userId) {
  const d = $.Deferred();
  setTimeout(function () {
    d.resolve({ userId: userId, name: "Alex" });
  }, 300);
  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

Returning a promise from pipe() pauses the chain until that promise resolves — the same pattern as chained AJAX calls in the reference, without needing real URLs.

📈 Practical Patterns

Nested Deferreds, error filters, and migration to then().

Example 3 — Parse and Enrich Data

Transform raw input, then return another Deferred for a follow-up step.

jQuery
const dfd = $.Deferred();
dfd.resolve('{"score": 88}');

dfd.pipe(function (jsonText) {
  const parsed = JSON.parse(jsonText);
  const next = $.Deferred();
  setTimeout(function () {
    next.resolve({ score: parsed.score, grade: "B+" });
  }, 200);
  return next.promise();
}).done(function (report) {
  console.log(report.grade);  // B+
});
Try It Yourself

How It Works

Combine synchronous parsing with async enrichment in one chain — the outer done() waits for the inner Deferred to resolve.

Example 4 — Error Mapping with failFilter

Pass null as doneFilter and handle rejection in the second argument.

jQuery
const dfd = $.Deferred();
dfd.reject("Network timeout");

dfd.pipe(null, function (reason) {
  return "Recovered: " + reason;
}).done(function (message) {
  console.log(message);
}).fail(function () {
  console.log("Still rejected");
});
Try It Yourself

How It Works

When failFilter returns a normal value, the piped chain can continue as resolved — similar to recovering in catch() / then() rejection handlers.

Example 5 — Migrate pipe() to then()

Same transform logic — modern jQuery 3+ code uses then() instead.

jQuery
const dfd = $.Deferred();
dfd.resolve(3);

// Legacy (deprecated in jQuery 3.0+)
dfd.pipe(function (n) {
  return n + 7;
}).done(function (legacy) {
  console.log("pipe:", legacy);  // 10
});

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

How It Works

For new code, replace .pipe(fn) with .then(fn). Replace .pipe(null, failFn) with .then(null, failFn) or .catch(failFn).

🚀 Use Cases

  • Sequential AJAX — load an ID, then fetch details based on that ID in one chain.
  • Data transformation — parse JSON, normalize fields, or compute derived values between steps.
  • Conditional branching — return different promises from a filter based on intermediate results.
  • Error recovery — map failures to fallback values with failFilter.
  • Legacy maintenance — read and gradually migrate existing pipe() chains to then().

🧠 How a pipe() Chain Flows

1

Resolve

Source Deferred settles with a value (or rejects).

Input
2

Filter

doneFilter or failFilter runs and returns the next value or promise.

Transform
3

Continue

Piped promise forwards the result to the next pipe(), then(), or done().

Chain
=

Composed workflow

Multiple async steps behave like one pipeline — prefer then() in jQuery 3+.

📝 Notes

  • pipe() is deprecated since jQuery 3.0 — use then() for new code.
  • Returning a value from done() does not affect the chain; use pipe() or then() for transforms.
  • Throwing inside a filter rejects the piped chain — same as returning a rejected promise.
  • Pass jQuery.noop or null to skip a filter slot when you only need fail or progress handling.
  • Always add fail() or catch() at the end of chains for user-facing error handling.

Browser Support

deferred.pipe() has been available since jQuery 1.7. It remains in jQuery 3.x but is deprecated — prefer then().

jQuery 1.7+

jQuery Deferred.pipe()

Works in jQuery 1.7+, 2.x, and 3.x. Deprecated since 3.0 in favor of then() for Promises/A+ compatibility.

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.pipe() Universal

Bottom line: Safe in legacy jQuery code. For jQuery 3+ greenfield projects, write .then() instead of .pipe().

🎉 Conclusion

The deferred.pipe() method transforms and chains asynchronous results through filter functions. It powered jQuery pipelines before Promises/A+ — today, then() is the recommended replacement.

Practice the five examples above, then continue to progress() to learn the listener side of progress reporting, or read the then() tutorial for modern chaining.

💡 Best Practices

✅ Do

  • Use then() in jQuery 3+ instead of pipe()
  • Return promises from filters for multi-step async work
  • Keep each filter focused on one transformation
  • Add fail() / catch() at chain end
  • Document what each chain step expects and returns

❌ Don’t

  • Use pipe() for side effects only — use done()
  • Forget error handlers on long chains
  • Mix unhandled thrown errors in filters
  • Assume legacy pipe() matches native Promise edge cases exactly
  • Chain real URLs without error handling (like bare example.com)

Key Takeaways

Knowledge Unlocked

Five things to remember about pipe()

Transform and chain jQuery Deferred values.

5
Core concepts
🔄 02

Return

Next input

Transform
🔗 03

Promise

Chain async

Sequence
04

failFilter

Recover/map

Errors
then 05

Modern

Use then()

jQ 3+

❓ Frequently Asked Questions

pipe() adds filter functions to a Deferred chain. On resolve, doneFilter receives the value and can return a transformed result or a new promise — the chain continues with that output. Optional failFilter and progressFilter handle rejection and progress paths.
Yes. pipe() is deprecated since jQuery 3.0 in favor of then(), which follows Promises/A+ semantics. pipe() still works in jQuery 3.x for legacy code; use then() in new projects.
done() only registers a side-effect callback — its return value is ignored. pipe() (and then()) use the filter's return value as the input for the next link in the chain.
A plain value (passed to the next step), another Deferred or promise (chain waits for it), or a rejected promise / thrown error (chain fails).
failFilter runs when the incoming Deferred rejects — useful for recovery or error mapping. progressFilter runs on notify() progress events and can transform progress values forwarded down the chain.
Prefer then(onFulfilled, onRejected) instead. It is the modern equivalent and matches native Promise chaining. Keep pipe() when maintaining older jQuery 1.x/2.x codebases.
Did you know?

jQuery added pipe() in 1.7 as a precursor to Promises/A+ chaining. When jQuery 3.0 aligned Deferreds with the Promise standard, then() became the official path forward and pipe() was marked deprecated — but millions of legacy plugins still call pipe() today.

Continue to 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.

6 people found this page helpful