How to Use jQuery Deferred .progress()
jQuery Deferred objects provide a way to handle asynchronous
operations, and the .progress() method is specifically
designed to listen for intermediate updates before the task completes or
fails. This article explains how to implement .progress()
to capture real-time status updates emitted by
deferred.notify(), complete with code examples, common
usage patterns, and key operational behaviors.
Understanding the
.progress() Method
When dealing with long-running tasks, such as file uploads, data
processing, or multi-step animations, users often need feedback before
the final completion. While .done() handles resolution and
.fail() handles errors, .progress() attaches
handlers that execute whenever the Deferred object calls its
notify() or notifyWith() methods.
Syntax:
deferred.progress( progressCallback [, progressCallback ] )Implementing
.progress() Step-by-Step
To track updates, you must create a Deferred object, emit progress
via notify(), and register the listener using
.progress() on either the Deferred or its generated
Promise.
1. Create an
Asynchronous Function Using notify()
The source operation uses deferred.notify() to emit data
to any listeners:
function performTask() {
var deferred = $.Deferred();
var count = 0;
var interval = setInterval(function() {
count += 25;
// Send a progress update
deferred.notify(count);
if (count >= 100) {
clearInterval(interval);
deferred.resolve("Task completed successfully!");
}
}, 500);
return deferred.promise();
}2. Listen for Progress Updates
Call the function and attach the .progress() handler
alongside standard completion handlers:
performTask()
.progress(function(percent) {
console.log("Current progress: " + percent + "%");
$("#progress-bar").css("width", percent + "%").text(percent + "%");
})
.done(function(message) {
console.log(message);
})
.fail(function(error) {
console.error("Task failed: " + error);
});Key Behaviors and Rules
- Notification Cutoff: Once a Deferred object is
resolved via
resolve()or rejected viareject(), calls tonotify()are ignored. Progress callbacks will no longer execute. - Late Binding: If you attach a
.progress()callback afternotify()calls have already been executed, the callback will not retroactively receive past notifications. It only executes for subsequentnotify()calls. - Passing Data: You can pass any data type through
notify(), including numbers, strings, or complex objects containing detailed status information (such as{ stage: 'uploading', bytesSent: 1048576 }). - Chaining: The
.progress()method returns the Deferred or Promise object, allowing it to be chained directly with.then(),.done(),.fail(), and.always(). Alternatively, you can pass progress callbacks as the third argument to the.then()method:deferred.then(doneFilter, failFilter, progressFilter).