jQuery Deferred & Promises


Warming: im not paying atention to correct spelling of words… lol.

DEFERRED

Since jQuery version 1.5 a new object called Deferred is available to use. It´s purpose is to manage callbacks of asynchronous (or not) events.

I found out about this just 2 days ago, lol… took me a while to understand it´s usefulness, but now i think i grasped it, so im writing this post as a way also to solidify the knew knowledge, it´s not meant as a tutorial…

So, what i understood is this:

A Deferred object represents a way to handle the completion, failure and progress events of some process (generaly, an async process). This object store in itself the status of this process and is in charge of doing all the appropiate callbacks based on it´s status. The usefulness of this object relies on it´s avility to add callbacks at any time and still do the correct calls when the status get´s resolved.

Basically, a process can be in 3 states: Pending, Resolved or Failed. This is obvious… so, the Deferred objects provies ways to set it´s internal state to this ones:

  • defered.resolve() = To dispatch that the process has finished successfully.
  • deferred.reject() = To dispatch that the process has failed.
  • deferred.notify() = To dispatch the progress state of the currently active process.

Thouse methods deals with the CHANGE of the internal´s status of the Deffered object. In general, only the creator of the Deferred object should be able to change/access this methods and no one else.

Now, to register callbacks to this states you have 5 ways to do this (you have more, but basically this are the basics)

  • deferred.done(…) = To register one or more callbacks to be called on success ( when deferred.resolve() get´s called )
  • deferred.fail(…) = Same as above but for failure ( deferred.reject() )
  • deferred.progress(…) = Same, but for deferred.notify()
  • deferred.then( suceesCallback, failCallback, progressCallback ) *handy to add the 3 types of callbacks at the same time.
  • deferred.always(…) = called always, regardless of success or failure.

Thouse are the basic methods, there are more, but this ones are the one you should understand first to learn this fast.

Ok, so that´s the interface that a Deferred object provides to handle it. On top of that jQuery provides some usefull methods to handle Deferred objects in more convenient way.

 

PROMISES

On top of the Deferred objects, the concept of a Promise is built. A Promise is an object that basically represents a process that is or will take place at some point in time, but allows you to register callbacks to it for when the process gets terminated or completed. It´s implemented as an object that only exposes a subset of methods of a Deferred objects. More specifically, the ones that allows you to add callbacks (done,fail, progress) but not the ones that let´s you change the status of the deferred (resolve, reject, notify)

Promises are not part of deferred objects, they are a concept. A Pattern to work arround events that takes place in uncertain times.

Deferred objects have a method called .promise() which returns an object that only exposes the means to register callbacks to it. Same as $.ajax which now returns an object that implements a Promise´s interface.

The concept of a Promise is usefull to help decouple the code that handles the process of a task, from the code that handles the actions that needs to get done after that task is done. You can work and do the same without implementing Promises or Deferred objects, but by using them you save a lot of time and complexity, the code also starts to look cleaner. And it´s easyer to code really, once you understand why this separation is needed.

For example, up to this point, i used to just type the callbacks of $.ajax calls inside the “setup” object (yeah, im lazy i know)… which mades the code looks kinda ugly when it gets bigger.

The thing about design patterns is that you can work without them, but understand them makes you use less brain neurons to do your daily work… is like weight training, it´s a pain in the ass, but the results are you needing less energy to move arround in your daily life. So what you think is a lot of work, in the end pays a lot more than what you invested.

Anyway, jQuery offers then a very usefull method to handle one or more promises (a.k.a tiny Deferred objects) called $.when. This methods takes one or more promises and creates one big promise that listens to all the promises it has and acts as a single one. This method returns a Promise (meaning, it has the same interface: done, fail, progress…)

 

CONCLUSION

This new objects are not new, just new ways to conceptualize tasks and to abstract ourselves when coding. To help decoupling and dealing with the new type of coding style that AJAX applications are making us deal with on our daily coding lifes.

Most people have problems learning new things because they espect to learn that: “new things”, so they cant process the fact that sometimes you dont need to learn new things, but to learn “new ways” of thinking with your same knowledge. You just change the way you look at things.

With the same knowledge of calling a function in javascript, you can abstract yourself from a task and create the concept of a promise. Same with the rest of the design patterns.

When i dont understand something, i generally stop and ask myself this question: -what i´m really trying to understand, what do i need to do?-

New things are generally old things with a diferent angle.

 

 

 

 

 

Advertisements