Question

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.

Was it helpful?

Solution

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').

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top