Monthly Archives: January 2014

Understanding JavaScript Promises In jQuery

You may or may not have heard the new buzz about promises being introduced into JavaScript and if you don’t know what they are, you’re not alone.  I’ll attempt to explain what they are and why you should or maybe shouldn’t care about them.  First let’s understand what promises are.

Promise defined: “The Promise interface represents a proxy for a value not necessarily known at its creation time. It allows you to associate handlers to an asynchronous action’s eventual success or failure. This let asynchronous methods to return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.”

Basically, it allows you to setup chaining for a value or values and determine a functional response.  For example, let’s say you need to get two values from two separate AJAX calls, but you don’t want to proceed unless both have loaded correctly and if either fails, you want to bail out of the entire thing.  Although not an optimum approach, this will serve as a more or less real world problem.  Consider the following code:

 

var first_call = false;
var second_call = false;
 
//make the first call
$.ajax({
    url: "/some/page",
    success: function(data){
        //set a success variable
        first_call = true;
    }
});
 
//make the second call
$.ajax({
    url: "/some/other-page",
    success: function(data){
        //set a success variable
        second_call = true;
    }
});
 
if(first_call && second_call){
    //we're good to go - do something
}
else{
    //ruh roh - bail out!
}

 

Now obviously, the above code isn’t fantastic but it will suit our needs for now.  Let’s walk through it.  The first ajax call if successful sets the first_call variable to true and the same goes for the second.  If all is good, we can proceed and do what we need to, otherwise we execute our bail out code.  So now let’s check out the same functional code executed with promises:

$.when( $.ajax("/some/page"), $.ajax("/some/other-page") )
    .done(function(first_call, second_call){
        //we're good to go - do something
    })
    .fail(function(){
        //ruh roh - bail out!
    });

So, looking at this latest example we see not only is the code much more compact, but now we can chain even more calls together, no use of outside variables for state checking and still we end up in the same place.  This is the power that promises provide you.  In the above example, we have implemented jQuery’s $.when call which will take a list of operations as the arguments.  For each operation, it will return the value into the done() function as the ordered arguments (ie. done(first_call_data, second_call_data, …)).  If a failure occurs for any of the calls, the fail() method is invoked where we can make use of our bail code and either try again, display an error message, etc.  If we wanted to add more calls to this promise we would do so by adding them directly to the when() function and creating the corresponding argument in the done() method.

$.when(
    $.ajax("/some/page"),
    $.ajax("/some/other-page"),
    $.ajax("/some/other-other-page"),
    $.ajax("/and/so/on")
    )
    .done(function(first_call, second_call, third_call, fourth_call){
        //we're good to go - do something
    })
    .fail(function(){
        //ruh roh - bail out!
    });

We can continue to chain $.when calls together to simply an otherwise complex system of dependencies.  Promises also provide us with a way of implementing our own custom promise behavior by taking advantage of methods such as .reject() .resolve() and .state().  However, this is a bit beyond the scope of this article.  For more information regarding jQuery promises have a look at:

Promise – http://api.jquery.com/promise/

Deferred Object – http://api.jquery.com/category/deferred-object/

JavaScript Worker Threads

Ever find yourself needing to do some number crunching, or create an off time rendering hook or perhaps just needing to create a separate thread for some other purpose, this is how you do it.  First things first, we need to create a separate javascript file which will house our thread execution code.  In this example, let’s create a file called “thread.js” and add the following:

function Thread(){
    var _ref = this;
    var _running = null;
 
    _ref.start = function(){
 
        //execution code
        function execute(){
            self.postMessage({
                cmd: "console.log",
                value: "Execute called..."
            });
        }
 
        _running = setInterval(execute, 1000);
    }
 
    _ref.stop = function(){
        clearInterval(_running);
    }
}
 
var thread = new Thread();
 
self.onmessage = function(e){
    thread[e.data.cmd](e.data.args);
}

So here’s what happening in this file.  We’ve created a class called “Thread” and created public methods “start” and “stop”.  Just for an example of functionality we’ve added an execute method loop which is invoked by a setInterval call every second (1000ms).  The “_running” variable is assigned the interval handle and cleared when the “stop” method is called.  Within the “execute” method the postMessage method is called which sends the message over the wall to our main execution script which we will detail below.  Lastly, we create an instance of the Thread class and create an “onmessage” handler to deal with incoming messages sent to our Thread class from over the wall in our main execution script.  Here, the Thread instance variable is invoked with the “cmd” parameter as the method and the “args” parameter as the arguments passed to the invoked method.  So here’s the main execution script that we will use to create an instance of the thread:

 

//create a worker thread
var worker = new Worker("thread.js");
 
//handle messages sent from Thread
worker.onmessage = function(e){
    switch(e.data.cmd){
        case "console.log":
            console.log(e.data.value);
            break;
    }
}
 
//start the Thread
worker.postMessage({cmd: "start"});
 
//stop the Thread after 5 seconds
setInterval(function(){
    worker.postMessage({cmd: "stop"});
}, 5000);

 

So let’s walk through the main script.  We create a instance of the “Worker” class and pass in the script we are going to use as our worker thread, in this case “thread.js”.  Next we setup an onmessage handler to receive messages sent from within our Thread.  Next we send a message with the cmd parameter set to start which over the wall evaluates to “thread.start()”.  Lastly, we setup an interval callback to be invoked after 5 seconds (5000ms) to stop the Thread.  Pie, right?  So now what if we want to add a method to the Thread class that takes in parameters and sends a value back to our main script…let’s do it:

function Thread(){
 
    //existing code omitted here...
 
    _ref.foo = function(args){
        self.postMessage({cmd: "console.log", value: args});
    }
}

So now we’ve added the method “foo” with arguments “args” and in turn we post a message back over the wall to the main script returning the “args” passed in as the value.  Now, let’s add the code to invoke it within our main script:

//existing code omitted here...
 
worker.postMessage({cmd: "foo", args: "bar"});

All we’ve done here is add another “postMessage” call with a “cmd” parameter of “foo” and an “args” parameter of “bar” which evaluates to “thread.foo(‘bar’)” on the other side of the wall within our Thread class.

D3 Drag And Drop

Implementing drag and drop in D3 (http://d3js.org/) is a pretty simple task when you know how to do it, the following is a walkthrough from setup to execution and the events along the way.

First thing we are going to want to do is setup our drag behavior.  This is the object that will be responsible for handling the actual drag and drop, events and will be added to the call chain of the objects of which we want to allow the drag and drop behavior.

var drag = d3.behavior.drag();

The above statement initializes a new instance of the drag behavior.  We can use it to bind this behavior to the call chain of other objects.  Let’s assume we want to allow all nodes having class “draggable” to have this drag and drop behavior.  To do this we simply add the drag behavior we just instantiated to the call chain of the objects:

var drag = d3.behavior.drag();
d3.selectAll(".draggable").call(drag);

It’s that simple, now all objects containing the “draggable” class will now have this behavior.  But what if we need to do something a bit more complex?  What if we need to have other things happen along the way, update other areas during a drag, initialize or change variables on start and end drag.

var drag = d3.behavior.drag()
    .on("dragstart", function(){
        //do some drag start stuff...
    })
    .on("drag", function(){
        //hey we're dragging, let's update some stuff
    })
    .on("dragend", function(){
        //we're done, end some stuff
    });

As you would expect, each on(…) call defines a hook into the event chain of the drag behavior allowing you to customize the behavior as you see fit.