I know async

If you are trying to pass arguments to a Node.js async.series  set of functions then this is going to help, I promise.

Imagine we have to methods in a Question-Answer website that we have to call before allowing a user to answer a Question.

We require the user to have enough reputation and also enough unicorns. Yeah, unicorns. This is an example, I can write anything here 😀

  • userHasEnoughReputation  that needs two parameters: user and question
  • userHasEnoughUnicorns  that also needs the same two parameters

We want to let async call those two methods, but the problem is that those functions need parameters, so what can we do?

I’m going to explain two ways to accomplish this:

  • With an object
  • With functions

Using an object

Those two methods can be related, and share parameters, so we can create an Object, and create it with the parameters we were trying to pass to our functions:

var AnswerPermissions = function(user, question) {

	this.user = user;
	this.question = question;

	this.userHasEnoughReputation = function(callback) {
		//Do something here with user and question and callback()
		callback('Here it is the result');
	};

	this.userHasEnoughUnicorns = function(callback) {
		callback('Sorry, not enough unicorns');
	};

}

And now you could call these functions with async:

var answerPermissions = new AnswerPermissions(user, question);
async.series([
		answerPermissions.userHasEnoughReputation,
		answerPermissions.userHasEnoughUnicorns
	],
	function(err, results) {
		if (err) {
			//oh shit
			return;
		}

		//all functions finished correctly!
	});

We could also add more functions, like: questionIsNotClosed() that only needs the question and not the user for example…

Anyways when this happens it means you might need an Object. You are doing something complex enough to create an Object with some properties shared across methods. That’s basically what an Object is meant for.

With functions

Another option is to give the methods more power. Creating an object can sound artificial, and if the functions you are trying to call with async do not share parameters, that’s even worse.

We are going to use .bind() to give those functions the expected parameters (user and question), and let async take care of the last parameter, the callback:

userHasEnoughReputation = function(user, question, callback) {
    //Do something here with user and question and callback()
    callback('done');
};

userHasEnoughUnicorns = function(user, question, callback) {
    //Do something here with user and question and callback()
    callback('done');
};

async.series([
    userHasEnoughReputation.bind(null, aUser, aQuestion),
    userHasEnoughUnicorns.bind(null, aUser, aQuestion)
],
function(err, results) {
    if (err) {
        //oh shit
        return;
    }

    //all functions finished correctly!
});

The null when using .bind() is to override the context or this for that function. We don’t need that in this example.

You can read more about bind here: MDN Function.prototype.bind()

Thanks to Gonzalo for the help with this functional approach 😀

Conclusion

Both ways are valid, and depending on the problem you are trying to solve maybe one way is better or makes more sense.

If you think my content is worth it you can Buy me a Coffee at ko-fi.com Buy me a Ko-fi