Daniel Fisher (lennybacon.com)

SOA, DATA & THE WEB

Chaining asynchronous javascript calls

The good thing about JavaScript is that its network/ajax calls are asynchronous. The bad thing about JavaScript is that its network/ajax calls are asynchronous.

It’s bad because nested calls increase complexity. Look at the following sample methods:

function f1(callback) { console.log('f1'); if (callback != null) { console.log('hasCallback'); callback(); } } function f2(callback) { console.log('f2'); if (callback != null) { console.log('hasCallback'); callback(); } } function f3(callback) { console.log('f3'); if (callback != null) { console.log('hasCallback'); callback(); } }

The calls should be executed one after another.

f3( function(){ return f2( function() { return f3(); } ); } );

Reading or even worst writing this makes me not happy. I don’t like the explicit nesting. It makes the code feeling complicate. It often don’t fits in the frame of 80 chars per line Sad smile.

Today I’ve put together a small helper class that collects calls and executes them by chaining them as callbacks.

var devcoach = devcoach || {}; devcoach.CallChain = function () { var cs = []; this.add = function (call) { cs.push(call); }; this.execute = function () { var wrap = function (call, callback) { return function () { call(callback); }; }; for (var i = cs.length-1; i > -1; i--) { cs[i] = wrap( cs[i], i < cs.length - 1 ? cs[i + 1] : null); } cs[0](); }; };

This few lines now let you write a more clear and easy to read calls automatically being nested calling the follower as callback.

var cc = new devcoach.CallChain(); cc.add(f1); cc.add(f2); cc.add(f3); cc.execute();

Comments

Write a comment