«

»

Jul 30

Print this Post

JavaScript promise

There is still this book on my shelf I am trying to finish: Head First Design Patterns. I know I could get a great knowledge, I do not have now, just by reading this book. But from the other site, I know that by only reading it I will not be able to make any use of that knowledge. So, I am still hoping I will start a series of posts about design patterns and using them with PHP. We will see…

Right now, I am getting known and using patterns we use in Wikia. One of recent ones every developer is encourage to use is the promise pattern knows in jQuery world as deffered object. As you might know from my previous posts [1, 2] or from Steve Souders’ books the performance golden rule is that front-end part of a website takes the most time of page loading in an end user’s browser. And to reduce this time one of the rules is to reduce HTTP requests our website is sending to the server. MediaWiki has its Resource Loader and it is a great tool to get some CSS stylesheets, javascript files in one request. But still the way it is written “traditionally” makes it a little bit unreadable.

Imagine we have a link and once it has been clicked an overlay layer is being displayed along with a DIV element over it. This DIV element contains a text with information what it is about and a button:

a simple bootstrap modal

We do not want to put this DIV in DOM once a page is loaded. What if a user does not click it? It will be a waste of bandwidth. It is better to load it on demand. But then we need to load the template and at least some styling for it. It will be at least two requests. What if we need additional JavaScript file with some logic for our DIV element or the button in the DIV? One request for the JavaScirpt file more. The pseudo javascript with jQuery would look like:

$.getResources(['modal.css', 'boostrap-modal.js'], function() {
   $.get('modal.php', function(template) {
      // once when we have all resources
      // modal.php -- the template
      // modal.css -- styling of the template
      // boostrap-modal.js -- some extra logic
      // we can display it
      $(document).html(template);
   });
});

The code is still not-so-bad. But imagine there are more and more complications and we need to put there more nested callbacks. It is getting more unreadable and maintenance of such a code is getting hard to do. More nested callbacks means more serialized HTTP requests — we should minimize this as well as we minimize the HTTP requests.

If we made $.getResources() and $.get()[3] promise compatible it will be easier to write, extend and maintenance:

// make all calls in parallel
$.when(
  $.getResources(['alert.css', 'alert.js']),
  $.get('alert.php')
).
done(function(dataFromGetResources, dataFromjQueryGet) {
  // called when both requested are completed
  // ...
}).
fail(function() {
  // something went wrong
  // ...
});

Isn’t it beautiful? And it works perfect! :) It makes the HTTP requests in parallel and it is easy to maintenance and extend. Of course you can not use promise pattern if one request depends on the response from the other one but it is the only disadvantage I recall at this moment. So, if we want to have a nice summary it would look like this:

Advantages

  • saves you from nested callbacks nightmare
  • several callbacks can be bound to the single promise
  • promises can be “wrapped” in a single promise
  • improves front-end performance by allowing HTTP requests to be made in parallel

Disadvantages

  • can’t use promises if at least one callback depends on results from another one

That’s all what I wanted to write :) If you are more interested how promise pattern works I can give you also a link to this deffered-js github project. There is a really nice explanation and you can use files of deffered-js in you small projects where you do not use jQuery in example.

References:

  1. Was Steve Souders wrong?
  2. Summary of “High Performance Web Sites” by Steve Souders
  3. jQuery.get() has already implemented promise interface

Permanent link to this article: http://blog.lukaszewski.it/2012/07/30/javascript-promise/

2 comments

  1. mheki

    Hejo hejo,
    fajny wpis – nie znałem tej metody. Co do wzorców zakupiłem sobie książkę Matta Zandstry PHP. Obiekty, wzorce, narzędzia – spis wszystkich wzorców na pierwszy rzut oka jest imponujący, jak przeczytam, dam znać czy warto kupić, Radek bardzo zachwala.
    Pozdro!

  2. andrew

    Promises became native JS part. Here is another nice article about them:
    http://www.sitepoint.com/six-things-might-know-promises/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>