I've been starting to play around with Node.js recently and I've come across a situation where I need a little guidance around the prescriptive node.js way of accomplishing a task. In this particular case I need to create a bunch of directories and, when all of the directories have been created I need to perform some final operation. The order in which the directories are created does not matter, I just need to perform a final operation after the last one is.

The easiest way the accomplish this would be to fall back to the old synchronous habits. That is, just call fs.mkdirSync for each of the directories and perform the operation at the end. For example:

fs.mkdirSync('a', 0755); fs.mkdirSync('a/b', 0755); fs.mkdirSync('a/b/c', 0755); performFinalOperation();

While this would work, it doesn't feel like it's the node.js way of doing it. Obviously, the program would block while it waits for the OS to create the directory and return. On a heavily loaded system with a file system that's mounted remotely each of the mkdirSync calls could take a very long time. So clearly, this isn't the best approach.

One of Node.js main selling points is the fact that it's asynchronous. So the calls to fs.mkdir could be chained through the callbacks:

fs.mkdir('a', 0755, function(e) { if (!e) { fs.mkdir('a/b', 0755, function(e) { if (!e) { fs.mkdir('a/b/c', 0755, function(e) { if (!e) { performFinalOperation(); } }); } }); } });

Again, this approach I'm sure works, but it leads to really deep nesting and code duplication. It does have the benefit of not blocking while the directories are created, but at what cost?

Another approach would be to get really fancy in an effort to avoid the code duplication and nesting:

(function (directories) { if (directories.length === 0) { performFinalOperation(); } else { var tail = arguments.callee; fs.mkdir(directories.shift(), 0755, function(e) { tail(directories); }); } })(['a', 'a/b', 'a/b/c']);

This approach makes use of all sorts of crazy stuff: anonymous self calling functions and the magical arguments.callee. But worst of all, it isn't obvious what the code is doing at first glance.

So, while the concrete question is around creating directories I'm more interested in the approach that a seasoned node.js veteran would take when this sort of situation arises. I'm specifically not interested in what libraries are around to make this easier.