deferred.progress() adds handlers that run when the Deferred sends progress notifications with notify() or notifyWith(). It is available since jQuery 1.7 and returns the same Deferred for chaining.
Remember
deferred.progress(progressCallbacks)
progress() → listen for updates
notify() → emit an update (owner)
done() → final success
fail() → final failure
progress can run many times while pending
native Promise has no progress API
Register listeners first, emit updates with notify(), then settle.
Create a Deferred (or receive one from an async helper).
Call progress(fn) — optionally add more handlers or arrays of handlers.
While work runs, call notify(args…) to fire those handlers.
When finished, resolve() or reject() — then use done() / fail().
Piece
Required?
Role
progressCallbacks
Yes
Function or array of functions
Extra callback args
Optional
More functions / arrays on the same call
Return
—
Same Deferred (chainable)
Since
—
jQuery 1.7
Pseudocode
Pseudocode
dfd = Deferred
handlers = []
progress(fn):
append fn to handlers
if dfd already resolved or rejected:
call fn immediately with last notify args
return dfd
notify(args…):
if dfd still pending:
for each handler: handler(args…)
remember args as last notify
resolve / reject:
settle dfd
// further notify() does not call progress handlers
Reference
Cheat Sheet
Keep these facts handy while wiring progress updates.
Topic
Detail
Syntax
deferred.progress(fn [, fn…])
Trigger
notify() / notifyWith()
vs done()
Many updates vs one success
Arrays
Pass a function or an array of functions
After settle
No new notify; late progress(fn) runs once with last args
Native Promise
No built-in progress channel
Since
jQuery 1.7
Try it
Live Preview
Pick a demo to see how progress() reacts to notify() and settlement.
Browser demo of deferred.progress — same idea as the examples below.
Chain handlers.progress returns the Deferred, so done / fail chain cleanly.
Notify twice. Progress logs step 1 and step 2.
Resolve.done logs ok finished; fail stays idle.
Try reject. Swap to reject to see the fail path instead.
Edge Cases & Pitfalls
Check these before relying on progress() in real projects.
order
Register before notify
Handlers attached after a notify() miss that update (unless the Deferred already settled — then late progress replays the last args only).
settle
No progress after settle
Once resolved or rejected, further notify() calls do not invoke progress handlers.
promise
Promise consumers cannot notify
Give callers promise() so they can attach progress / done but cannot call notify or resolve.
native
Not in native Promises
progress / notify are jQuery Deferred features. Do not expect the same API on Promise.
Compatibility
Browser Support
deferred.progress() needs jQuery 1.7+ loaded. It works in jQuery 1.7–3.x alongside notify() / notifyWith().
✓ jQuery 1.7+
deferred.progress()
Works in Chrome, Firefox, Safari, and Edge when jQuery 1.7+ is loaded. Pair with notify() to emit updates.
100%With jQuery 1.7+
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
progress()Universal
Bottom line: Safe wherever jQuery 1.7+ Deferreds are available. Remember: native Promises have no progress channel.
Analysis
Performance Notes
Approach
Cost
Best for
progress + rare notify
Cheap
Step labels, coarse percent
notify every tick
Can flood UI
Throttle (e.g. every 5–10%)
done / fail only
Cheapest
When mid-flight UI is not needed
Progress handlers are ordinary callbacks. Avoid notifying on every byte or animation frame unless the UI can keep up — batch or throttle updates.
Remember
Key Takeaways
Role: listen for interim notify() updates.
Pair:progress for updates, done/fail for the end.
Chain: returns the same Deferred — stack more handlers freely.
Late attach: after settle, progress(fn) runs once with last notify args.
One line:progress() listens; notify() speaks — use them for mid-flight updates before done or fail.
Frequently Asked Questions
progress() adds handlers that run when the Deferred generates progress notifications via notify() or notifyWith(). It does not settle the Deferred — resolve() and reject() still control the final outcome.
done() runs once on successful resolve. progress() can run many times while the Deferred is pending. Use progress for interim updates; use done for the finish.
notify() and notifyWith() on the same Deferred. Each call invokes every registered progress callback with the arguments you passed.
Yes. progress() accepts a function or an array of functions, and you may pass multiple arguments (each a function or array).
New notify() calls no longer fire progress handlers after settlement. But a progress callback added after resolve/reject runs immediately with the arguments from the last notify()/notifyWith().
No. Progress notifications are a jQuery Deferred feature. Native Promises only fulfill or reject — use separate callbacks, events, or other patterns for mid-flight updates.