How to Create a jQuery Deferred Object
This article provides a straightforward guide on how to create and use a jQuery Deferred object to manage asynchronous operations in JavaScript. You will learn the basic syntax for instantiation, how to manipulate the object's state using resolution and rejection methods, and how to expose a restricted Promise object to ensure safe code execution.
To create a new jQuery Deferred object, call the
$.Deferred() factory method:
var deferred = $.Deferred();Understanding the Lifecycle
A Deferred object starts in a pending state and can transition to one of two final states:
- Resolved: Indicates that the asynchronous action succeeded.
- Rejected: Indicates that the asynchronous action failed.
Once a Deferred moves to a resolved or rejected state, it remains in that state and cannot change again.
Core Methods
deferred.resolve(args): Resolves the Deferred object and calls anydoneCallbackswith the supplied arguments.deferred.reject(args): Rejects the Deferred object and calls anyfailCallbackswith the supplied arguments.deferred.notify(args): Triggers anyprogressCallbacksto indicate ongoing progress before the object is resolved or rejected.deferred.promise(): Returns the Promise counterpart of the Deferred object. The Promise contains methods to attach callbacks (.done(),.fail(),.then()) but prevents external code from resolving or rejecting the state.
Implementation Example
The most common design pattern is creating a Deferred object inside a
function, performing an asynchronous task, and returning its
.promise():
function fetchUserData(userId) {
// 1. Create the Deferred object
var dfd = $.Deferred();
// 2. Perform an asynchronous action
setTimeout(function() {
if (userId) {
// Resolve with data on success
dfd.resolve({ id: userId, name: "Alice" });
} else {
// Reject with an error on failure
dfd.reject("Invalid user ID provided.");
}
}, 1000);
// 3. Return only the promise to protect the deferred state
return dfd.promise();
}
// Consuming the returned Promise
fetchUserData(42)
.done(function(user) {
console.log("User retrieved:", user);
})
.fail(function(error) {
console.error("Error:", error);
})
.always(function() {
console.log("Request completed.");
});Passing a Constructor Function
You can also pass an optional function directly into
$.Deferred(). The new Deferred instance is passed as both
the first argument and the this context to that
function:
var dfd = $.Deferred(function(newDeferred) {
// Automatically called upon creation
newDeferred.resolve("Completed immediately");
});
dfd.done(function(message) {
console.log(message);
});