Pages

Saturday, December 21, 2013

Event Driven Asynchronous Callbacks in node.js


In J2EE Servlets, which I previously used for web application development, each request is handled by a separate java thread. The whole requests runs on that thread unless we create a new thread to do things inside it. PHP also does work in a similar way. But node is quite different in this. Node works as a single process. If there is a slow part somewhere in the program, then the whole process will be slow, and no other requests will be taken up in the meantime. This may be heard as a very big disadvantage, but there is a workaround that makes node.js advantageous over others. That is by using Event Driven Asynchronous Callbacks.



In my last post, the sample code written was
var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Yes Boss! Thats it!");
  response.end();
}).listen(9090);

This actually is not the right way to write a node.js code. It works fine, but it is best if the code is written as follows :
var http = require("http");

function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Yes Boss! Thats it!");
  response.end();
}

http.createServer(onRequest).listen(9090);

console.log("Continuing with the rest of my work!");

'Why' is the question, right?
Imagine you are the doing an academic project with 4 of your other friends and you are the team leader. You have decided certain tasks for yourself, and others. Now you want to give others their work. In a usual programming scenario, every line executes after its previous line has been completed. By that method, you will give one guy a work, wait for him to complete that, report back, and then gives the other guy his work.. and so on.. and finally after 4 people has completed the work, you start to do your work. That is how a normal code works, right? But is that effective? How should it actually be? You assign work to the first guy and asks him where to keep his report on completing his work, do the same with the next guy and so on, and then immediately start working on your work. Your friends will do their work and complete it at different time and report them one by one. This is how node.js works. Everyone (everything) works in parallel. This method is called Event Driven Asynchronous Callback (Such a big name for a small thing, huh? Its not a small thing, its something great).
A variation of this example is given by Felix Geisendörfer on this blog post.

Lets leave the project thingy and get to a sample code:

var names = database.query("SELECT Last_Name FROM Employee");
console.log("Going to the rest of my unrelated works.. ");

This is not the correct form of querying a db, this code is just for purpose of explaining the post. So in this code as you can see is a db query. The code will move on only after the query, which may take some time. The query may actually be performed externally by the DBMS, but the node process will have to wait for it to complete and return to do the unrelated tasks that follows. The problem can be worse on a scenario where such statements are looped

for(var i=0;i<100;i++){
var names = database.query('SELECT Last_Name FROM Employee WHERE mgrid=?',i);
}
console.log("Going to the rest of my unrelated works.. ");

Now process have to wait the query to occupy 100 times one after another. So to prevent this, as we discussed earlier, we have to allow each query to work parallelly and specify what to do after completion.

To accomplish this, we define a function that says what to do after completion of the query and makes the query aware of that. Example:

function responseReady(response){
         //do something with the response
         console.log(response)
}
database.query('SELECT Last_Name FROM Employee', responseReady);
console.log("Going to the rest of my unrelated works.. ");

This will initialize the database query, allow it to execute while the process continues with its unrelated works. When the query is completed, it calls the responseReady function which processes the response. This is possible because database querying is the part of an asynchronous library in node.

Now I guess you understood, why we are doing it the other way when both of them are nearly the same and does the same purpose. You will understand more when working with node. Even if you didn't understand it, don't let this ruin your interest to learn node. Keep Coding!

No comments:

Post a Comment