Victus Spiritus

home

The joy of function chaining and callbacks with jQuery and underscore.js

29 Jan 2011

What language features do you rely on while coding? In my own work and others' code (while wearing my app developer hat) I look for the following utilities:

  1. readability (minimize line noise and arcane symbols/parens)
  2. mostly working code (see 1)
  3. powerful data and algorithmic manipulation
  4. light interface definitions from structure or runtime symbols (boo to static typing/complex inheritance)
  5. efficiency whenever practical (impatient, frugal)

The above priority set leads to trade offs. What I'm learning more about today will help with everything on that list. Function chaining helps with 1-4. The chain leads to readable code that works, enables powerful manipulation of data and processing, and can be a light interface in dynamic scripting languages (like javascript). Callbacks aid 4-5 by providing functional flexibility (execute this code block when you're done) and prevent blocking code from slowing event driven software down (gui's, distributed apps, servers). Let's jump right in with specific examples of chaining and callbacks with javascript.

Chaining Examples

Ultra-Chaining with jQuery captures John Resig's early thoughts on how jQuery would handle chaining, and those ideas have matured in the latest library releases. Here's a straight forward example of chainable animation effects from the web designer wall

The following is a live example of the above code:
[iframe http://jsfiddle.net/victusfate/GQG4F/1/embedded/result/ 500 400]

Process Chaining
Thanks to Henrik Joreteg (a talented web hacker at andyet.net) for calling underscore.js to my attention yesterday.
[blackbirdpie url="http://twitter.com/HenrikJoreteg/status/30859394296057856"]
(emphasis mine).

Underscore.js

Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects. It's the tie to go along with jQuery's tux.

For another great example of function chaining see the following:

Callback Examples

The jQuery documentation on callbacks gives a few one line descriptions for callback functions with and without arguments.

CALLBACK AND FUNCTIONS

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed. The special thing about a callback is that functions that appear after the "parent" can execute before the callback executes. Another important thing to know is how to properly pass the callback. This is where I have often forgotten the proper syntax.
</blockquote.
Good, Callback without arguments

$.get('myhtmlpage.html', myCallBack);

Bad, WRONG way to pass callbacks with args

 $.get('myhtmlpage.html', myCallBack(param1, param2));

Good, Right way to callback with args

$.get('myhtmlpage.html', function(){
  myCallBack(param1, param2);
});

JavaScript: The Good Parts
Javascript: The Good Parts discusses callbacks in detail.

Callbacks

Functions can make it easier to deal with discontinuous events. For example, suppose there is a sequence that begins with a user interaction, making a request of the server, and finally displaying the server's response. The naïve way to write that would be:

request = prepare_the_request(  );
response = send_request_synchronously(request);
display(response);

The problem with this approach is that a synchronous request over the network will leave the client in a frozen state. If either the network or the server is slow, the degradation in responsiveness will be unacceptable. A better approach is to make an asynchronous request, providing a callback function that will be invoked when the server's response is received. An asynchronous function returns immediately, so the client isn't blocked:

request = prepare_the_request(  ); 
send_request_asynchronously(request, function (response) {     
  display(response);     
});

We pass a function parameter to the send_request_asynchronously function that will be called when the response is available.

example of callback, hitting the twitter search api
And for kicks I put together a simple code sample that exercises callbacks by hitting the twitter api (the git repo for callback_twitter_sample):

Here's the app live, feel free to play with it, fork it etc.
[iframe http://victusfate.github.com/callback_twitter_sample/ 500 500]

Related urls: