jQuery Deferred and Promises

Deferred and Promises are tools provided by jQuery to handle asynchronous tasks, such as AJAX requests, animations, or other operations that take time to complete. They simplify the management of callbacks and provide a clean way to chain asynchronous operations.

What is Deferred?

A Deferred object is a way to manage the success, failure, and progress of asynchronous tasks. It can be used to:

  1. Attach multiple callbacks (success, failure, progress).
  2. Chain multiple asynchronous actions.
  3. Trigger actions when an operation succeeds or fails.

Basic Methods of a Deferred Object

Method Description
$.Deferred() Creates a new Deferred object.
resolve() Marks the Deferred object as successful.
reject() Marks the Deferred object as failed.
done() Attaches a success callback.
fail() Attaches a failure callback.
always() Attaches a callback that runs regardless of success or failure.
then() Attaches both success and failure callbacks, and allows chaining of operations.

Example 1: Basic Use of $.Deferred

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Deferred Example</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
    <div id="output"></div>
    <script>
        $(document).ready(function() {
            function asyncTask() {
                var deferred = $.Deferred();

                setTimeout(function() {
                    var isSuccess = Math.random() > 0.5; // Random success or failure
                    if (isSuccess) {
                        deferred.resolve("Task succeeded!");
                    } else {
                        deferred.reject("Task failed!");
                    }
                }, 2000);

                return deferred.promise(); // Return a promise
            }

            asyncTask()
                .done(function(message) {
                    $("#output").text("Success: " + message);
                })
                .fail(function(error) {
                    $("#output").text("Error: " + error);
                })
                .always(function() {
                    console.log("Task completed (success or failure).");
                });
        });
    </script>
</body>
</html>

Try It Now

What is a Promise?

A Promise is an immutable object that represents the eventual completion or failure of an asynchronous operation. In jQuery, the Deferred.promise() method generates a Promise object. Unlike a Deferred object, a Promise can only be used to attach callbacks and not to resolve or reject the operation.

Example 2: Using Promises with AJAX

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Promises Example</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
    <div id="output"></div>
    <script>
        $(document).ready(function() {
            function fetchData() {
                return $.ajax({
                    url: "https://jsonplaceholder.typicode.com/posts/1",
                    method: "GET"
                });
            }

            fetchData()
                .done(function(data) {
                    $("#output").html("<strong>Title:</strong> " + data.title);
                })
                .fail(function() {
                    $("#output").text("Error fetching data.");
                })
                .always(function() {
                    console.log("AJAX call completed.");
                });
        });
    </script>
</body>
</html>

Try It Now

 

Example 3: Chaining with then()

You can chain multiple asynchronous tasks using then().

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Deferred Chaining</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
    <div id="output"></div>
    <script>
        $(document).ready(function() {
            function firstTask() {
                var deferred = $.Deferred();
                setTimeout(function() {
                    deferred.resolve("First task completed.");
                }, 1000);
                return deferred.promise();
            }

            function secondTask() {
                var deferred = $.Deferred();
                setTimeout(function() {
                    deferred.resolve("Second task completed.");
                }, 1000);
                return deferred.promise();
            }

            firstTask()
                .then(function(message) {
                    $("#output").append("<p>" + message + "</p>");
                    return secondTask();
                })
                .then(function(message) {
                    $("#output").append("<p>" + message + "</p>");
                });
        });
    </script>
</body>
</html>

Try It Now

Example 4: Multiple Deferred Objects with $.when()

$.when() allows you to wait for multiple Deferred objects to complete.

<!DOCTYPE html>
<html>
<head>
    <title>jQuery $.when() Example</title>
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
</head>
<body>
    <div id="output"></div>
    <script>
        $(document).ready(function() {
            function task1() {
                var deferred = $.Deferred();
                setTimeout(function() {
                    deferred.resolve("Task 1 completed");
                }, 1000);
                return deferred.promise();
            }

            function task2() {
                var deferred = $.Deferred();
                setTimeout(function() {
                    deferred.resolve("Task 2 completed");
                }, 2000);
                return deferred.promise();
            }

            $.when(task1(), task2())
                .done(function(result1, result2) {
                    $("#output").html("<p>" + result1 + "</p><p>" + result2 + "</p>");
                });
        });
    </script>
</body>
</html>

Try It Now

Key Points to Remember

  1. Deferred vs Promise
    • A Deferred object can resolve or reject an operation.
    • A Promise is a subset of Deferred and only allows you to attach callbacks.
  2. Chaining
    • Use then() to chain multiple asynchronous tasks together.
  3. Error Handling
    • Always attach fail() to handle errors gracefully.
  4. Waiting for Multiple Tasks
    • Use $.when() to coordinate multiple Deferred objects.

Summary

  • jQuery Deferred and Promises provide an elegant way to handle asynchronous operations.
  • They help manage complex chains of tasks with clear and maintainable code.
  • Use .done(), .fail(), .always(), and .then() to attach callbacks and manage asynchronous flows.
  • Combine multiple operations with $.when() for better control.