jQuery noConflict() Method
A Deferred is a jQuery object that represents a task that will complete in the future. A Promise is the read-only view of a Deferred — you can attach callbacks to it but cannot resolve or reject it. Together, they provide a clean way to manage asynchronous code without deeply nested callbacks.
The Problem: Callback Hell
Without Deferred, async code becomes deeply nested and hard to read.
// Callback hell — hard to read and maintain
$.get("step1.php", function(result1) {
$.get("step2.php?data=" + result1, function(result2) {
$.get("step3.php?data=" + result2, function(result3) {
// Now do something with result3
// And what if any of these fail?
});
});
});
The Solution: Deferred + Promises
// Clean, readable, with error handling
$.get("step1.php")
.then(function(result1) { return $.get("step2.php?data=" + result1); })
.then(function(result2) { return $.get("step3.php?data=" + result2); })
.then(function(result3) {
console.log("All done:", result3);
})
.fail(function() {
console.log("Something went wrong in the chain.");
});
Diagram: Deferred States
Deferred Object: ┌────────────────────────────────────────────┐ │ State: PENDING ← initial state │ │ │ │ │ ┌──────┴──────┐ │ │ │ │ │ │ RESOLVED REJECTED │ │ (success) (failure) │ │ │ │ │ │ .done() runs .fail() runs │ │ │ │ .always() runs in BOTH cases │ └────────────────────────────────────────────┘
Creating a Custom Deferred
function loadUserData(userId) {
var dfd = $.Deferred();
$.get("api/user.php", { id: userId })
.done(function(data) {
if (data.found) {
dfd.resolve(data.user); // success path
} else {
dfd.reject("User not found."); // failure path
}
})
.fail(function() {
dfd.reject("Network error.");
});
return dfd.promise(); // return the read-only promise
}
// Usage:
loadUserData(42)
.done(function(user) {
$("#name").text(user.name);
})
.fail(function(errorMsg) {
$("#error").text(errorMsg);
});
$.when() — Wait for Multiple Async Tasks
$.when() takes multiple Deferred or Promise objects and waits for all of them to complete before running the .done() callback.
// Load two API endpoints simultaneously, then run when BOTH are done
$.when(
$.get("api/products.json"),
$.get("api/categories.json")
)
.done(function(productsResult, categoriesResult) {
var products = productsResult[0];
var categories = categoriesResult[0];
renderProducts(products, categories);
})
.fail(function() {
$("#error").text("Failed to load data.");
});
Diagram: $.when() Parallel Execution
$.when(requestA, requestB) Time → requestA starts ─────────────────── resolves at 300ms requestB starts ─────── resolves at 200ms $.when waits for the SLOWEST (requestA at 300ms) .done() runs at 300ms with both results
then() vs done() — Key Difference
.done(fn) → callback runs on success; chaining after done() does not wait for fn .then(fn) → callback runs on success; chaining after then() DOES wait for fn to resolve // then() is more powerful for sequential async steps promise.then(step1).then(step2).then(step3); // Each step waits for the previous to complete
Deferred with a Timer
function waitFor(ms) {
var dfd = $.Deferred();
setTimeout(function() {
dfd.resolve("Done waiting " + ms + "ms");
}, ms);
return dfd.promise();
}
waitFor(2000).done(function(msg) {
console.log(msg); // "Done waiting 2000ms" after 2 seconds
});
notify() and progress() — Track Progress
function processItems(items) {
var dfd = $.Deferred();
$.each(items, function(i, item) {
// Notify progress percentage
dfd.notify(Math.round(((i + 1) / items.length) * 100));
});
dfd.resolve("All items processed.");
return dfd.promise();
}
processItems([1, 2, 3, 4, 5])
.progress(function(percent) {
$("#progressBar").css("width", percent + "%");
})
.done(function(msg) {
console.log(msg);
});
Quick Summary
- A Deferred object represents a future result — it starts pending and settles as resolved or rejected.
- A Promise is the read-only interface of a Deferred — attach callbacks but cannot change the state.
.done(fn)runs on success;.fail(fn)runs on failure;.always(fn)runs in both cases.$.when(p1, p2)waits for multiple promises before running a shared callback..then()is best for sequential async steps — each step waits for the previous one.
