← Back to jQuery Course | Chapter 12: Deferred & Promises | Lesson 1 of 5

Introduction to Deferred Objects

A Deferred object represents an asynchronous operation. It can notify other code when the operation succeeds or fails.
Syntax
javascript
var dfd = $.Deferred();

dfd.done(function(value) { /* success */ });
dfd.fail(function(reason) { /* failure */ });
dfd.always(function() { /* either way */ });

dfd.resolve(value);   // or dfd.reject(reason);

What is a Deferred Object?

A Deferred object wraps an asynchronous task and exposes methods to announce when that task eventually succeeds or fails. It's jQuery's own implementation of the promise pattern, built before native Promises existed in JavaScript, and it still underlies every jQuery AJAX call today.

Example: What is a Deferred Object?

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <div id="output"></div>
  <script>

    $("#runBtn").click(function() {
      const dfd = $.Deferred();
      $("#output").text(String(dfd.state()));
    });

    $("#resetBtn").click(function() {
      $("#output").empty();
    });
  </script>
</body>
</html>

Why Use Deferred?

Deferred objects help separate an asynchronous task from the code that eventually uses its result, so the code that starts the task doesn't need to know who's listening for it to finish. This separation makes callback-heavy code much easier to organize and reason about, especially once multiple things depend on the same result.

Example: Why Use Deferred?

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <div id="output"></div>
  <script>

    $("#runBtn").click(function() {
      function loadData() {
        const dfd = $.Deferred();
        setTimeout(function() { dfd.resolve("data ready"); }, 100);
        return dfd.promise();
      }
      loadData().done(function(result) { $("#output").text(JSON.stringify(result)); });
    });

    $("#resetBtn").click(function() {
      $("#output").empty();
    });
  </script>
</body>
</html>

Deferred and Callbacks

done() registers a callback for successful completion, fail() registers one for rejection, and always() registers a callback that runs no matter which outcome happens — similar to a try/catch/finally block but for asynchronous code. You can attach multiple callbacks of each type, and jQuery calls all of them in the order they were added.

Example: Deferred and Callbacks

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <div id="output"></div>
  <script>

    $("#runBtn").click(function() {
      $("#output").empty();
      const dfd = $.Deferred();
      dfd.done(function() { $("#output").append($("<div>").text("Success")); });
      dfd.fail(function() { $("#output").append($("<div>").text("Failed")); });
      dfd.always(function() { $("#output").append($("<div>").text("Always runs")); });
      dfd.resolve();
    });

    $("#resetBtn").click(function() {
      $("#output").empty();
    });
  </script>
</body>
</html>

Deferred Promise

A promise exposes the done, fail, and always methods of a Deferred without exposing resolve or reject, so code that only observes the result can't accidentally control it. This is the standard object to return from a function, so callers can react to the outcome without being able to interfere with it.

Example: Deferred Promise

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <div id="output"></div>
  <script>

    $("#runBtn").click(function() {
      const dfd = $.Deferred();
      const promise = dfd.promise();
      promise.done(function() { $("#output").text("Observed"); });
      dfd.resolve();
    });

    $("#resetBtn").click(function() {
      $("#output").empty();
    });
  </script>
</body>
</html>

Small Deferred Project

Deferred objects are a good way to see asynchronous flow explicitly: the task is started immediately, but its outcome is only reported later once it actually completes, whether that's a timer, an animation, or a network request finishing.

Example: Small Deferred Project

javascript
<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <style>
    button { padding:6px 14px; margin:4px; background:#2c6aa0; color:white; border:none; border-radius:4px; cursor:pointer; }
    #resetBtn { background:white; color:#2c6aa0; border:1px solid #2c6aa0; }
    #output { margin-top:10px; padding:8px; border:1px solid #ccc; border-radius:4px; background:#f7f7f7; font-family:monospace; min-height:24px; }
  </style>
</head>
<body>
  <button id="runBtn">Run</button>
  <button id="resetBtn">Reset</button>
  <div id="output"></div>
  <script>

    $("#runBtn").click(function() {
      $("#output").empty();
      const dfd = $.Deferred();
      $("#output").append($("<div>").text("Task started"));
      setTimeout(function() {
        dfd.resolve("Task complete");
      }, 200);
      dfd.done(function(msg) { $("#output").append($("<div>").text(String(msg))); });
    });

    $("#resetBtn").click(function() {
      $("#output").empty();
    });
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Calling resolve() and expecting done() callbacks added afterward to be ignored, when jQuery still runs them immediately.
  2. Returning the Deferred itself to callers, letting them call resolve(), when you should return dfd.promise().
  3. Forgetting to call resolve() or reject() anywhere, so the callbacks never run and the task stays pending.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.