Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Writing clean code with a callback pattern vs. deferreds.

Guidelines

  1. Only nest the simplest of functions
  2. Give functions a name
  3. Seems weird to pass callback function as an argument

The callback way

async.parallel([
        function(callback){
            callback(null, 'one');
        },
        function(callback){
            callback(null, 'two');
        }
    ],
    // optional callback
    function(err, results){
        // the results array will equal ['one','two']
    }
);

Which is more readable if you name your functions...

async.parallel([
        function doOne(callback){
            callback(null, 'one');
        },
        function doTwo(callback){
            callback(null, 'two');
        }
    ],
    function allDone(err, results){
        // the results array will equal ['one','two']
    }
);

But it's still weird to pass functions as arguments... so here's the deferred way.

jQuery.when(
    function doOne() {
        firsting = jQuery.Deferred();
        firsting.resolve('one');
        return firsting.promise()
    },
    function doTwo() {
        seconding = jQuery.Deferred();
        seconding.resolve('one');
        return seconding.promise()
    }
).done(function allDone(results) {

})
.fail(function failed(err) {
    // called as soon as deferred fails (rejected)
});

It's way more readable if you define your functions first. Here's the readable way

function doOne() {
    firsting = jQuery.Deferred();
    firsting.resolve('one');
    return firsting.promise()
}

function doTwo() {
    seconding = jQuery.Deferred();
    seconding.resolve('two');
    return seconding.promise()
}

function allDone(results) { 
};

function onFailure(err) {
}


$.when(doOne(), doTwo())
    .done(allDone)
    .fail(onFailure);

// and best of all... with coffeescript:

doOne = ->
  firsting = jQuery.Deferred();
  firsting.resolve('one');
  firsting.promise()

doTwo = ->
  seconding = jQuery.Deferred();
  seconding.resolve('two');
  seconding.promise()
    
$.when(doOne(), doTwo())
  .done (results) ->
    # done
  .fail (err) ->
    # fail

Here's the coffeescript version of the original, which gets worse as doOne and doTwo become more complicated. Also, still confusing that callback maps to results... but I guess you could say the same about resolve() and when.

async.parallel([
  (callback) ->
    callback(null, 'one');
, 
  (callback) ->
    callback(null, 'two');
], (err, results) ->
  # the results array will equal ['one','two']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment