Uncategorized

Fixing async.waterfall parameter handling

Users of node.js should be familiar with the excellent async library for wrangling some of Node’s async craziness. One thing that frustrates me is when using async.waterfall you can’t easily vary the number of parameters passed. Two uses cases occur for this: one: skipping to the end, and two: just straight up ignoring results.

A typical example looks like this:

    async.waterfall([
        ... // some functions skipped that may or may not set "skip" flag
        function (cb) {
            if (skip) return cb();
            model.companies.get(user.company.id, cb);
        },
        function (c, cb) {
            if (skip) return cb();
            // do something with c...

However that fails under normal async because it cares about the number of parameters passed to cb() matching those of the next function.

I managed to fix that by monkeypatching async.iterator as follows:

// Async monkeypatch
async.iterator = function (tasks) {
    var makeCallback = function (index) {
        var fn = function () {
            if (tasks.length) {
                var args = Array.prototype.slice.call(arguments);
                while (args.length < tasks[index].length) {
                    args.unshift(null);
                }
                tasks[index].apply(null, args.slice(Math.max(0, arguments.length - tasks[index].length)));
            }
            return fn.next();
        };
        fn.next = function () {
            return (index < tasks.length - 1) ? makeCallback(index + 1): null;
        };
        return fn;
    };
    return makeCallback(0);
};

All it does is make sure the number of parameters matches, filling in nulls when required, or truncating as required.

Hope you find this useful.

Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s