What is jquery Deferred and Promise?


jQuery the java-script framework help us to write concise java-script code, in this blog I am going to introduce about powerful feature of jQuery some people found it difficult to understand or ignore/forgot it once they done with the task.

So let's begin:
The definition of deferred and promise can be found easily by googling it :-), so we are directly begin with the implementation or coding.
Since most of the developer are familiar with ajax so first I would like to start with ajax and then we will look how to use deferred.

A html div :-
<div id="mydiv">
</div>
<div id="mydiv2">
</div>

js code :-
$.ajax({
url:'/echo/json/',
  context:document.body,
  success:function() {
  $('#mydiv').text('ajax success');
  },
  error:function() {
  $('#mydiv').text('ajax error');
  }
});

Here success and error handlers are the callback functions and will be invoked when ajax succeeded or failed respectively.
from jQuery version 1.6 a little addition to the ajax request is made, now it can be written like

var ajax1 = $.ajax({
url:'/echo/json/',
  context:document.body
});

ajax1.done(function() {
    $('#mydiv').text('ajax success');
});

ajax1.fail(function() {
    $('#mydiv').text('ajax fail');
});

so what's the big deal, its just appears to be a syntactical difference but wait.............
Here we can have a series of done and fail statements like:-

ajax1.done(function() {
    $('#mydiv').text('ajax success');
});

ajax1.done(function() {
    $('#mydiv').append('again ajax success');
});

That's cool right? you can now group your logical blocks into the small done/fail callbacks.
Instead of done and fail you can use success and error but the later syntax is in favour to use done and fail callbacks.

Now lets move on to the another feature of the promise .then.
Instead of explaining then theoretically, look at the code snippet.
ajax1.then(successCallback, failCallback);
many of you may got it correctly if not don't worry, I am sure at least 50% of the code you understood.
we know in javascript we can do functional programming so successCallback and failCallback is nothing but the variables that are assigned to the functions which will be call when success or failure of the ajax. We can have a series of then too. Cool ......
Simple code snippet for successCallback and failCallback

var successCallback = function() {
$('#mydiv').append('ajax then with success ');
};

var failedCallback = function() {
$('#mydiv').append('ajax then with failed ');
};

Now we are about to finish the promise by covering one feature, i.e. $.when
Let's assume you are in the situation where you want to execute a some functionality on success or failure of multiple ajax request.

In that case its difficult to trace a multiple ajax calls since they are may be async requests how you can achieve this? answer is pretty simple use $.when
$.when(ajax1, ajax2).then(successCallback, failedCallback);
and you are done !!
If any of ajax in this case ajax1 or ajax2 fails then failedCallback gets invoked and if both are succeeded then  only successCallback gets invoked.
That all !!
Before moving to the next section I suggest try executing all these scenarios by yourself, I have created a fiddle containig all the scenarios discussed above. Each commented section in the fiddle is a standalone code so try executing all scenarios by uncommenting the sections.
Link: https://jsfiddle.net/kulbhushanchaskar/dfofxhg6/

Time to learn deferred:-
What if somebody ask you to implement your own promise?
let's do it now.........

Try to understand following code snippet:-
var work = function() {
   var num = 2;
   var anothernum = 3;
   var def = $.Deferred();//line 1
  //def.resolve(num);//line 2
  def.reject(anothernumber); // line 3
  
  return def.promise(); //line 4
};

Whats happening in the work function?
@ line 1: $.Deferred() returns the deferred object and assigns it to the def variable
@ line 2: Resolving the deferred. It means if I comment line 3 (uncomment line 2) and returns the promise then work().done(function(num) {}); will get invoked
@ line 3: Rejecting the deferred, It means the promise then work().fail(function(num) {}); will get invoked
you can catch the value of parameters passed from def.resolve(2); in done/fail as written in line 2 and 3

That's how easy it is..... :-)

What if I simply returned def instead of def.promise()?
Yes it is possible to return only deferred but it is error prone because somebody might call def.resolve() when you actually reject it in work function so best practices is to return promise than deferred. promise is the read-only version of deferred so no one can reject or resolve your promise.

I have created fiddle for this too please check and try yourself.
Link: https://jsfiddle.net/kulbhushanchaskar/g44ufjc6/

Done !! 

--Kulbhushan Chaskar.

Comments

Popular posts from this blog

ResultSet as Stream in Java

Teiid - Simplifies Data Virtualization