Alexandru Rosianu Alexandru Rosianu - 1 month ago 6
Node.js Question

async.apply inside async.waterfall

I have the following snippet of code

async.waterfall([
// Read directory
async.apply(fs.readdir, '../testdata'),
// Load data from each file
function(files, callback) {
async.each(files, loadDataFromFile, callback);
}
], function(err) {
if (err) {
api.logger.error('Error while inserting test data', err);
}
next();
});


Is there a way I could replace this piece:

function(files, callback) {
async.each(files, loadDataFromFile, callback);
}


with just a function? Like I did above, using
async.apply()
I replaced this:

function(callback) {
fs.readdir('../testdata', callback);
}


I know I could create my own helper function to do this, or I can leave it like this, but I was wondering if there's a way to do this using only functions like
.bind()
or
.apply()
.

I've thought about using
.bind()
then
.apply()
but this would result in
function(loadDataFromFile, files, callback)
which is not okay.

Answer

I was wondering if there's a way to do this using only functions like .bind() or .apply().

Not using only native functions, or only those from async it seems. As you have noticed, one would need to flip the each function. Some implementations of partial application (like Underscore) allow intermediate arguments, but you would need to explicitly include them.

An example with lodash's partialRight:

async.waterfall([
  _.partial(fs.readdir, '../testdata'), // Read directory
  _.partialRight(async.each, loadDataFromFile), // Load data from each file
], function(err) {
  if (err)
    api.logger.error('Error while inserting test data', err);
  next();
});

Possible you will need to bind the method to the correct context though, like fs.readdir.bind(fs, '../testdata').

Comments