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.

Leave a Comment

Your email address will not be published. Required fields are marked *