JayData.org

How to handle asynchronous programming in JayData

Author: Hajnalka Battancs May 1st, 2012


If you come from a serverside programming background like me, the wildly asynchronous nature of data access in Javascript can be a bit of an inconvenience. I made this short tutorial to help keep your head and your code straight.

The classic way of handling asynchronicity in Javascript is by passing a callback function to the operation call. JayData of course supports this on all “terminator” methods, with the simplest case of passing a callback function:

Or to facilitate error handling, passing both a success and an error callback as parameters, or a handler object with a method named success and another named error.

This is perfectly okay, as long as you are waiting on a single operation in order to do something. However, it might happen that you need the result of not one, but two operations – two queries from the same datasource, or aggregating data from different sources (which seems like the way to go these days with all the mashup applications around).

Using the above scheme becomes extremely troublesome in such cases. Embedding one call in the callback of the other may work, but will incur a heavy penalty, as two queries that could run side by side, will have to run in sequence instead. Overcoming this obstacle is possible only with a deep understanding of concurrent programming, the Javascript language, and way more code than should be necessary for something like this.

For that reason, we opted to make use of the jQuery deferred object in JayData. All terminator methods that can be called with a callback function can also be called empty, in which case they will return a deferred object, or as we like to call it, a promise object.

You can learn all about the deferred object in the jQuery reference, its basic use isn’t all that different from the classic way of doing things:

However, its power starts to shine through in the scenario I mentioned above. Let’s say, we need the list of all departments, and all employees for some in-memory data crunching. This means two independent asynchronous operations that must be finished before something could be done.

And this does exactly what you’d want it to do.

Now there is one last thing I’d like to get into. As I mentioned, I’m a serverside guy by origins, and the use-case where the operations depend on each other does in fact bug me a bit. Now it seems straightforward, putting the dependent call in a callback is perfectly justified, and is in fact the right way to go. My problem is more a code management issue. Too many embedded functions, too many levels and brackets, it just makes code horribly hard to read.

Here’s what I suggest for situations like that:

As you can see, the code is in order of execution, and despite the multiple callbacks, it is equally readable to sequential, synchronous code. And besides, you might actually want to reuse the functions you factored out from a monster callback parameter in this way.