Getting comfortable with Javascript callbacks

It seems every language has it’s own way of implementing callbacks.

Back in the VB days (daze?) we used the addressof operator and all kinds of win32 stuff to get app and activex control to do what we wanted.

In C#, we have the delegate (and the anonymous delegate) that makes life pretty easy in terms of defining how to subscribe to a callback “even” and how to broadcast that callback.

 

Javascript callbacks are the simplest, and arguable the more nebulous, implementation of them all.  Once you understand how callbacks work, using libraries like jQuery, and our own UGC Javascript API becomes much easier.

Why do we need it?

Think of the way code normal iterates from line to line.  It’s straightforward and simple: you loop over a list, and at the end of the loop, you keep going; you use an if statement, and after that you know that the condition has been met; similarily, when you call a method, you know that it has done all of its work and returned something useful.  Right?  Well… not always.  Sometimes that method will invoke web requests that need some time to process, or it may call another method that has to do some processing or is waiting for user input…  These kinds of operations can be implemented asynchronously, and the only way to manage that logic programmatically is with a callback parameter.

How does it work?

A callback parameter on a Javascript method is essentially passing a reference to the enter function definition into the method so that the method can call that function when it needs to.

Here’s an example:

 

function doSomething(callback) {
    if (somecondition()) {        
      callback(true);
    }
}

function entryPoint() {
    doSomething(function(yesOrNo) {
       //do something else
    });
}

Let’s assume that the entryPoint() method is being called first.  It calls doSomething(), which in turn exits right away.  The only way that the entryPoint method will know what the doSomething method wanted to return is to pass in a function as a callback, and take the return value as parameter.  In this case, it’s a boolean value, but it could be anything (or more that one thing).

A lot of the useful methods in the jQuery library use this logic, especially the unobtrusive event handlers on buttons or links.

$("#btnSubmitForm").click(function(e) {
    e.preventDefault();
    //do something
});

Notice how the click method takes a function parameter, which in turn has a “e” parameter with the event data from the button click.

Now let’s look at how Urls can be invoked asynchronously (remember the first letter of the AJAX acronym is asynchronous).

$.ajax({
  url: 'path/handler.ext',
  success: function(data) {
     //do something with the data
  },
  error : function(request, errorType, exception) {
     //handle the error
  }
});

You’ll notice that this implementation is a bit different – the ajax method from jQuery is passed an object that has several fields defining how that method is meant to behave.  The first one here is the Url, which will be invoked.  Then we have 2 separate functions that are passed in – one for the success condition that is passed the data that was returned from the Url handler, and another with the error condition. 

There is also a way to invoke the ajax method synchronously, such that it blocks the calling method until the web request handling is complete, but that may cause the user’s browser to appear frozen if the request takes a long time, so be super careful with this one.

var html = $.ajax({
  url: "filepath.ext",
  async: false
 }).responseText;

There are lots of other things to consider when using callbacks in Javascript.  Mostly, you’ll need to be able to quickly refer to whatever documentation is available so that you can determine with the expected parameters and fields are for each callback function itself.

 

more later – joel

No Comments