Popular Control Flow Libraries

14 Nov 2011 | By Alex Young | Tags node async

When writing asynchronous code it quickly becomes apparent that certain patterns are more natural than others. These patterns are fairly generic, so many people have started to rely on control flow libraries rather than reimplementing the same patterns.

There are a lot of control flow libraries for Node, and they all solve the same problems in subtly different ways. Some are more accurate than others with regard to established nomenclature, particularly when it comes to design patterns that were already popular in other languages.

People usually discover the need for control flow libraries when running something like this:

files.forEach(function(file) {
  fs.readFile(file, function() {
    // Callback
  });
});

A set of files is going to be read with an asynchronous callback. That’s great, but what happens when we need to determine when every callback has finished?

One solution is to use a counter:

files.forEach(function(file) {
  fs.readFile(file, function() {
    // Callback
    fileCount--;
    if (fileCount === 0) {
      events.emit('complete');
    }
  });
});

events.on('complete', function() {
  // All files have been processed
});

However, adding a few more levels of asynchronous dependencies will make this hard to manage. This is where libraries step in to provide another layer of abstraction.

One such library is Tim Caswell’s Step, which is probably the first control flow library I saw:

Step(
  function readSelf() {
    fs.readFile(__filename, this);
  },
  function capitalize(err, text) {
    if (err) throw err;
    return text.toUpperCase();
  },
  function showIt(err, newText) {
    if (err) throw err;
    console.log(newText);
  }
);

There are dozens of other, similar libraries available through npm. Which one should you use? I’ve made a table of the popular ones to try to get a handle on the situation. Post your favourites in the comments and I’ll take a look at them.

Name NPM License Dependent Packages GitHub Watchers Features Browser Support
Async.js async MIT 129 982 Parallel execution of ‘functional’ methods, generic parallel, serial, and waterfall methods Yes
Step Step MIT 42 462 Parallel and serial execution, error handling, grouping Yes
Futures futures MIT 6 190 Promises, “joins”, events, chained sequences, method queues, sequences Yes
Seq seq MIT/X11 14 124 Sequential and parallel execution, error handling, chained API No

blog comments powered by Disqus