roastie
roastie

Reputation: 307

jQuery's Deferred callback execution sequence

jQuery's Deferred/promise has two outcomes: resolved and rejected. You can attach callbacks to the Deferred which are associated with either state. The conditions for attachment are done (associated with resolved), fail (associated with rejected), and always (associated with both states). I have unsuccessfully been trying to determine the sequence of the callbacks when the state moves from pending to non-pending; i.e., for done and always (or fail and always), what is the sequence in which the callbacks execute for each state of resolved and rejected?

Upvotes: 20

Views: 6188

Answers (2)

TachyonVortex
TachyonVortex

Reputation: 8602

@Malcolm's answer is indeed correct. The docs mention it in many places, including:

  • deferred.done() and deferred.fail()"Callbacks are executed in the order they were added."
  • deferred.always()"When the Deferred is resolved or rejected, callbacks are executed in the order they were added"
  • jQuery.ajax()"Promise callbacks — .done(), .fail(), .always(), and .then() — are invoked, in the order they are registered."

Implementation details

Looking at the Deferred module, it uses the Callbacks module which implements a FIFO "callback list".

Here's the call stack for adding callbacks to a Deferred object:

And here's the call stack for resolving/rejecting the Deferred object:

Upvotes: 14

Malcolm O'Hare
Malcolm O'Hare

Reputation: 5009

Deferred objects process their callbacks in the order that the callback was added to the deferred object. There is no precedence to done() over always(), or vice versa. The behavior is identical whether you call resolved() or reject().

Please see the following jsfiddle example.

The comments on the original question are not correct, or at least not completely correct.

Upvotes: 6

Related Questions