Search

Tuesday, October 1, 2013

Switching from Synchronous to Asynchronous

Recently, we decided to switch from Python/Django to Node.js/Express due to the customer requirement. This required a huge change in design paradigm for us: a switch from synchronous programming to asynchronous programming. In synchronous, you have to wait for the previous command to be completed before the next command is executed. In asynchronous way, the next command can be executed without blocking from long running command. The style of coding have to be changed. Callback function becomes important role to let you know that the long running command has been finished.

Asynchronous VS Synchronous

Synchronous ensures the sequence of the command execution. The next command will not be executed unless the previous one is finished.

var data = dbCall();
returnData(data);

If dbCall is synchronous method to connect to database to get the data, returnData is blocked and have to wait until dbCall is finished and return data.

Asynchronous is non-blocking, the application can run the next command while waiting for the previous command to be finished. This is very useful for application with long running command like I/O execution. Let’s see the previous example.

var data = dbCall();
returnData(data);

Suppose that dbCall is asynchronous method which connect to database and get the data. The function returnData will be executed immediately after calling dbCall no matter the dbCall is finished or not. This will be the problem since returnData is supposed to send the data returned from dbCall but data may not be assigned. What if we want to ensure that the previous command is finished before running the next one in order, callback takes important role for this. In this case, callback function is passed as a parameter to dbCall and called back after the asynchronous function is finished.

var callback = function(data){
returnData(data);
};
dbCall(callback);

The function dbCalled should look something similar to this.

var dbCall = function(callback){
// connect to database and get data
// this is executed asynchronously
// and do callback after getting data
db.getData().success(function(data)){
callback(data);
}
};

The callback function is called when dbCall got the data.

If the function returnData takes the same parameter as the callback function we can simply modify the code to be more simple.

dbCall(returnData);

Frontend developers may be used to asynchronous paradigm already since a lot of web development is event driven. Users trigger the event to execute the function. The very simple example is the JQuery on change event.

$('input').change(function(){
 alert('The text has been changed.');
});

There is no looping to wait for the input the be changed but the function is trigger when the change event occur.
Another example is ajax request.

$.ajax({
url: '/ajax',
type: 'GET',
done: function(res){
alert(res);
},
fail: function(){
alert('error');
}
});

Done represents the callback function to be called when it successes, while fail represents the callback function to be called when error occurs.



Introduction to Node.js


Node.js is a JavaScript platform that allow you to run JavaScript code in the backend. It builds on Google’s V8 which is Chrome’s JavaScript runtime.

The following code is the simple web server run at port 8080 written in Node.js.

var http = require('http');
http.createServer(function (request, response) {
 response.writeHead(200, {'Content-Type': 'text/plain'});
 response.end('Hello World');
}).listen(8080);

The function createServer is asynchronous function which will return a newly created web server object and add the anonymous callback function(request listener) to the request event.

The code can be executed using node command from command line.

node sample.js

It will return “Hello World” to the browser when you request for http://localhost:8080.

For more information about Node.js, please visit Node.js official website.


JavaScript Closure


Closure is one of the most frequently used features in JavaScript. It allows an inner function to access the variables and parameters of the outer function.

function outer(a){
var b = 5;
function inner(){
console.log(a+b);
}
inner();
}

The inner function can access the parameter(a) and variable of the outer function. When you call outer(3), it will print 8 to the console.

> outer(3)
8

Be careful of having closure in a loop. Since the outer function pass the variable by reference, the variable of the outer function can be change from time to time. This can cause the problem since we will never know when the command line that uses the outer variable is executed. It is not guaranteed that the value is the value that we expected by the time it is executed.

function doLoop(){
for(var i=0;i<5 i="" span="">
setTimeout(function(){
console.log(i)
}, 100)
}
}

From the example above, the next loop is executed immediately after the setTimeout function is called. This causes the variable i to be changed to 5 by the time it is printed in the inner function. The output is “5” printed 5 times to the console which is what not we expect.

Since javascript variable scope is in function scope, we can avoid this error by wrapping the function and pass the parameter to the function instead.

var doSomething = function(i){
setTimeout(function(){
console.log(i)
}, 100)
}
function doLoop(){
for(var i=0;i<5 i="" span="">
doSomething(i);
}
}

When we run doLoop() from the code above, the output will be as expected.
0
1
2
3
4


Since this is our first project in Node.js, we have faced a lot of problem in the beginning. This let us learn a lot and gain experiences in different aspects especially to think and design in asynchronous way as well as to have better understanding of callback function and closure too. Since these are different approaches, it depends on how you application works.If your application requires a lot of long running commands like I/O tasks, asynchronous will allow your application to handle something else while waiting for the background task which can be more utilized without blocking. Otherwise, as my own opinion, synchronous programming have simpler structure.

3 comments:

  1. The article was up to the point and described the information very effectively. Thanks to blog author for wonderful and informative post.
    website development Pakistan

    ReplyDelete
  2. Great job, this is essential information that is shared by you. This information is meaningful and very important for us to increase our knowledge about it. Always keep sharing this type of information. Thanks once again for sharing it.

    3d Game Development Company

    ReplyDelete
  3. Very well written article. It was an awesome article to read. Complete rich content and fully informative. I totally Loved it.
    Best Satta Matka App

    ReplyDelete