Difference Between jQuery Promise and Deferred
In jQuery, both Deferred and Promise objects are used to handle asynchronous operations, but they serve fundamentally different roles in managing task states. The core difference lies in control: a Deferred object represents the work itself and possesses the methods to trigger state changes (resolving or rejecting the task), whereas a Promise is a read-only representation of that Deferred object, allowing consumers to listen for completion without having the ability to alter its state.
The Deferred Object: The Controller
A Deferred object starts in a pending state and acts as the producer of an asynchronous operation. It contains the logic to change its own state and notify any attached listeners.
A Deferred object includes state-altering methods such as:
deferred.resolve(args): Manages success by moving the state from "pending" to "resolved" and executing anydonecallbacks.deferred.reject(args): Manages failure by moving the state from "pending" to "rejected" and executing anyfailcallbacks.deferred.notify(args): Triggers progress callbacks before the object is resolved or rejected.
Because these control methods are publicly exposed on the Deferred instance, passing it directly to outside consumers creates a risk: any receiving code could prematurely resolve or reject the operation, interfering with the intended asynchronous flow.
The Promise Object: The Observer
A Promise is an abstraction derived directly from a Deferred object
by calling deferred.promise(). It provides a safe interface
intended for consumers.
A Promise exposes methods for attaching handlers, but completely omits methods that modify state:
- Observation methods included:
.done(),.fail(),.always(),.then(), and.state(). - Mutation methods omitted:
.resolve(),.reject(),.notify(),.resolveWith(), and.rejectWith().
By returning only the Promise to callers, the producer ensures that the state of the operation can only be altered by the function that created the Deferred object.
Comparison Summary
| Feature | jQuery Deferred | jQuery Promise |
|---|---|---|
| Role | Producer / Controller | Consumer / Listener |
| Can resolve/reject? | Yes (resolve(),
reject()) |
No (Read-only) |
| Can attach callbacks? | Yes (done(),
fail(), then()) |
Yes (done(),
fail(), then()) |
| Primary Use Case | Inside the asynchronous function | Returned to external callers |
Practical Workflow
In standard jQuery development, you instantiate a Deferred object inside an asynchronous function, perform the asynchronous task, and return its Promise to the caller:
function fetchUserData() {
var dfd = $.Deferred();
setTimeout(function() {
var success = true;
if (success) {
dfd.resolve({ id: 1, name: "Alice" });
} else {
dfd.reject("Failed to load user");
}
}, 1000);
// Return only the Promise to protect the Deferred state
return dfd.promise();
}
// Consumer code
var userPromise = fetchUserData();
userPromise.done(function(user) {
console.log("User retrieved:", user.name);
});
// userPromise.resolve() does not exist, preventing unauthorized manipulation.Functions like jQuery.ajax() follow this exact design
pattern: internally they manage a Deferred object to handle network
responses, but they return a Promise-compatible jqXHR object to prevent
external code from manually resolving or rejecting the active network
request.