Quick introduction to Async programming in Node.JS

Posted by

So many things in node.js run async (a-synchronized). Mostly I/O operations like: File system, Database queries, Network communication, etc. Thanks to async node programs can serve multiple users running on a single thread and since node is single threaded no locking and synchronizations are needed.
But this makes it very difficult for coders to write and understand the flow of async code. The main problems is that unlike natural understatement, when you look at async programming, the orders of the lines of code are not the execution order meaning that line #2 can run before line #1.

Dealing with async code is complex but there are some methods which make it easier. Here we will describe the 3 main ways to write async code in Node.js:
Callback Functions
Promises
Yield

The original way of responding to an async function call is using a callback function. The idea is that we pass a function (pointer to a function) to the async function so when it ends it will call the callback function.
For example:

db.insert(‘hello’, function(err,res){
	console.log(‘Completed inserting to DB’);
});

In this code we insert an object to a MongoDB database. When the function completes it will call the function(err, res) and that’s where we put our response code.

The problem with this method is what’s called “callback hell”. Assuming we need to chain several functions and call them one after the other our code will look something like this:

db.insert({str:‘hello’}, function(err,res){
	console.log(‘Completed inserting to DB’);
	var id = res._id;
	db.update({id:id, data:’aaa’}, function(err, res){
		http.send(‘http://server.com/’ + res, function(err,res){
			db.insert({id:id, response:res},function(err, res){
				console.log(‘Done!’);
			});
		});
	});
});

Another problem is that it’s difficult to separate functionality to different modules or even different classes. Say if you wanted to put the http call in another function of some other object that accepts data as input and returns the response it will be difficult since you will need to define callbacks that depend on each other in a very confusing way.

The next method is using Promises. Promise is a standard (spec) which was implemented by many frameworks such as BlueJ, Q, and others. So you first need to include one of these in your project. The promise wraps the callback in a way that makes it easy to return values from async functions. The values that are returned are not the returned value of the callback itself, they are a special object called a Promise. So our previous code (assuming db functions return promises) will look like this:

db.insert({str:‘hello’}, function(err,res){
	console.log(‘Completed inserting to DB’);
	var id = res._id;
	return db.update({id:id, data:’aaa’}).then(function(err, res){
		return http.send(‘http://server.com/’ + res).then(function(err,res){
			return db.insert({id:id, response:res}.then(function(err, res){

			});
		});
	});
}).then(function(res){	
	console.log(‘completed’);
});

The main advantage in Promises is the ability to return the Promised object so some other function, perhaps in a different module can process it and you don’t have to write your code in the ‘callback hell’ syntax. The promise as a then method which will execute once the async function completes. It also has an error function for error handling. And if a function in the Promise chain throws an exception the parent promise will throw it to the caller so you don’t need to worry about errors on each level.

Next post we will talk about yield and EcmaScript6 (ES6)

Leave a Reply

Your email address will not be published. Required fields are marked *