jQuery Deferred & Promises

When code involves tasks that take an unknown amount of time — like AJAX requests, animations, or timers — it becomes necessary to manage what happens after those tasks complete. jQuery's Deferred and Promise objects provide a clean, structured way to handle these asynchronous operations.

What is a Deferred Object?

A Deferred represents a task that has not yet completed. It can be in one of three states:

  • Pending: The task is still in progress.
  • Resolved: The task completed successfully.
  • Rejected: The task failed.

Think of a Deferred like a food order at a restaurant. When placed, the order is pending. When the food arrives, it is resolved. If the kitchen runs out of ingredients, it is rejected.

What is a Promise?

A Promise is a read-only view of a Deferred. It allows other parts of the code to react to the outcome (success or failure) without being able to change the outcome. The Deferred controls the state; the Promise is shared with other code to listen for that state.

Creating a Deferred

var deferred = $.Deferred();

setTimeout(function() {
  var success = true;

  if (success) {
    deferred.resolve("Task completed successfully!");
  } else {
    deferred.reject("Task failed.");
  }
}, 2000);

var promise = deferred.promise();

.done() .fail() .always()

  • .done() — Runs if the Deferred is resolved (success)
  • .fail() — Runs if the Deferred is rejected (failure)
  • .always() — Runs regardless of success or failure
promise
  .done(function(message) {
    $("#status").text("SUCCESS: " + message);
  })
  .fail(function(message) {
    $("#status").text("FAILED: " + message);
  })
  .always(function() {
    $("#spinner").hide();
  });

Complete Working Example

function fetchData() {
  var deferred = $.Deferred();

  setTimeout(function() {
    deferred.resolve({ name: "Alice", score: 98 });
  }, 1500);

  return deferred.promise();
}

$(function() {
  $("#loadBtn").click(function() {
    $("#result").text("Loading...");

    fetchData()
      .done(function(data) {
        $("#result").text(data.name + " scored " + data.score);
      })
      .fail(function() {
        $("#result").text("Failed to load data.");
      });
  });
});

$.when() — Waiting for Multiple Promises

$.when() takes one or more promises and returns a new promise that resolves only when all given promises have resolved. If any one is rejected, the whole thing is rejected.

Example: Wait for Two AJAX Calls

var getUsers    = $.getJSON("users.json");
var getProducts = $.getJSON("products.json");

$.when(getUsers, getProducts)
  .done(function(usersData, productsData) {
    var users    = usersData[0];
    var products = productsData[0];
    console.log("Users: " + users.length + ", Products: " + products.length);
  })
  .fail(function() {
    alert("One or more requests failed.");
  });

Chaining with .then()

The .then() method accepts success and failure callbacks, and returns a new promise — enabling sequential async chains.

function step1() {
  return $.Deferred(function(d) {
    setTimeout(function() { d.resolve("Step 1 done"); }, 500);
  }).promise();
}

function step2(msg) {
  return $.Deferred(function(d) {
    setTimeout(function() { d.resolve(msg + " -> Step 2 done"); }, 500);
  }).promise();
}

step1()
  .then(function(result) {
    console.log(result);      // "Step 1 done"
    return step2(result);
  })
  .then(function(result) {
    console.log(result);      // "Step 1 done -> Step 2 done"
  });

AJAX Requests Already Return Promises

jQuery's AJAX methods already return jqXHR objects that implement the Promise interface.

$.get("profile.json")
  .done(function(data) {
    $("#name").text(data.name);
  })
  .fail(function() {
    $("#name").text("Could not load profile.");
  })
  .always(function() {
    $("#loadingMsg").hide();
  });

Key Points

  • A Deferred represents an async task; a Promise is the read-only view of that Deferred.
  • .done() handles success, .fail() handles failure, .always() handles both.
  • $.when() waits for multiple promises to all complete before running a callback.
  • .then() chains sequential async operations cleanly.
  • All jQuery AJAX methods return a jqXHR object that supports the Promise interface.

Leave a Comment

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