Well, here is a simple implementation for a chain of functions, queuing them up.
First of all, the function:
function waterfall(arr, cb){}
Now we need to track the array and repeat it:
function waterfall(arr, cb){ var fns = arr.slice();
Let's start by processing the passed and empty array by adding an additional parameter so that we can pass the results around result :
function waterfall(arr, cb, result){
Which is nice:
waterfall([], function(err, data){ console.log("Done!"); });
Now, they say, actually the handle in the file:
function waterfall(arr, cb, result){ // result is the initial result var fns = arr.slice(1); // make a copy, apart from the first element if(!arr[0]){ // if there is nothing in the first position process.nextTick(function(){ // don't cause race conditions cb(null, result); // we're done, nothing more to do }); return; } var first = arr[0]; // get the first function first(function(err, data){ // invoke it // when it is done if(err) return cb(err); // early error, terminate entire call // perform the same call, but without the first function // and with its result as the result waterfall(fns, cb, data); }); }
And this! We overcome the fact that we cannot iterate over calls using recursion basically. Here is a script illustrating this.
It is worth noting that if we implemented it using promises, we could use a for loop.