Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 311
roastie Avatar asked May 01 '13 02:05

roastie


People also ask

What is the difference between a Deferred and a Promise?

A promise represents a value that is not yet known. This can better be understood as a proxy for a value not necessarily known when the promise is created. A deferred represents work that is not yet finished. A deferred (which generally extends Promise) can resolve itself, while a promise might not be able to do so.

What is Deferred () used for?

Deferred() method. It can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function. The Deferred object is chainable, similar to the way a jQuery object is chainable, but it has its own methods.

How use jQuery Deferred and Promise?

If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred. promise() so other code can register callbacks or inspect the current state. For more information, see the documentation for Deferred object.


1 Answers

@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:

  • always()
    • done() / fail()
      • Callbacks.add()
        • list.push() – The callback function is pushed onto the end of the list.

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

  • resolve() / reject()
    • resolveWith() / rejectWith()
      • Callbacks.fireWith()
        • Callbacks.fire() – The callbacks in the list are executed in FIFO order using a for loop.
like image 95
TachyonVortex Avatar answered Oct 11 '22 17:10

TachyonVortex