The servers like apache tomcat, Joss, apache..etc those are multi-threaded HTTP server which means for each and every request that the server receives, it creates a separate thread which handles that request.

Node.js is an event driven programming language which runs in a single thread. So in Node.js how multiple requests works is, for Every I/O call requires you to register a callback. So every I/O call also returns immediately, this allows you to do multiple IO operations in parallel without using thread. When the I/O operation is completed its callback will be pushed on the event loop. The event loop is In an event-driven application, there is generally a main loop that listens for events, and then triggers a callback function when one of those events is detected.

The following diagram shows the workflow of user request in node.js Server

Node programming model

First let's compare how the code written in asynchronous and synchronous way. Below shows the synchronous code (typical way) for fetching a query from the database.


var conn = getDbConnection(connectionString);
var stmt = conn.createStatement();
var result = stmt.executeQuery(sqlQuery);
for(var i=0;i < results.length;i++){
//print results[i]
}

But in asynchronous programming the above code will not give the correct result. Below shows the asynchronous way of programming for above same code.


getDbConnection(connectionString,function(err, conn){// callback function
con.createStatement(function(err,stmt){// callback function
var result = stmt.executeQuery(sqlQuery);
results.on('row',function(result)){
//print result
}
})
}) 

If you look at the above program you can find that some functions parameter become another function. For example in above asynchronous example getDbConnection function, the first parameter become the connection string which is same as the connection string in above synchronous example and the second function is the callback function and which will trigger after the completion of getDbConnection function. Here callback function having two parameters one is error param and other one is connection param(which return by the getDbConnection). Inside of the callback of getDbConnection function does the statement creation function which is also implemented like a callback scenario.

The line "results.on('row',function(result))" means an event editor. We will look more into an event emitor later.

We can write asynchronous functions as in two ways,

1. One is write call back function as a seperate block like follows.


var handler = function(error,results){
//if error is undefined
//do your further operation
}

executeMyFunction(inputParam, handler);

In above the executeMyFunction(inputParam, handler) become an asynchronous function and handler(error,results) become its handler function. Above in handler function, the error parameter tells if any errors happen while fetching the asynchronous result. So in the handler before you are going to do something you must need to check if the error is undefined.

2. Second one is write the call back function as Anonymous function.

In this case we can add the function inside the parameter list like follows


executeMyFunction(inputParam, function(error, results){
//if error is undefined
//do something with the results
})


Another advantage of the anonymous functions are the usage of closure. We will discuss the detail of closure in another post

Christmas Tree Problem

One of the main problem if anonymous way of calling asynchronous function is Christmas Tree Problem Christmas tree problem is something like call an asynchronous function from another asynchronous functions anonymous handler. This results in some issues in code understandability and maintenance in future.


async1(inputParam, function(err,results1){
 async2(result1, function(err,result2)){
  async3(result2, function(err,result3)){
   //and so on....
  }
 }
})

Node tackles the problem leveraging javascript's language features to make this model a little more synchronous-looking by inducing the programmer to employ a certain programming style. Every function that requests IO has a signature like function (... parameters ..., callback) and needs to be given a callback that will be invoked when the requested operation is completed (keep in mind that most of the time is spent waiting for the OS to signal the completion - time that can be spent doing other work). Javascript's support for closures allows you to use variables you've defined in the outer (calling) function inside the body of the callback - this allows to keep state between different functions that will be invoked by the node runtime independently.

Create a Server in Node

Lets create the first program with node. If you are familar with the servers like tomcat or apache, you can start those server by download the server and click on the currosponding startup bat file. But in the case of node its something different. For starting a node server in a port, you want to write a few lines of codes. Below shows a sample code that explains how to start a node server.

Step 1: Create an empty js file (say Server.js) and fillup that js file with following lines of code


var http = require('http');
http.createServer(function(req, res){
res.writeHead(200,{'Content-Type':'text/plain'});
res.end('Hello Behindjava, Servlet Started :)\n');
}).listen(8080);
console.log('Server started!!!');

Above lines of code means "Start a http server in port 8080. Also put the string 'Hello Behindjava, Servlet Started :)' as the server response"

Step 2: you can run the above code using node <Js file name>; command.

Step 3: After starting the server if you request the 8080 port through your browser you can find that the string "Hello Behindjava, Servlet Started :)"

2 comments:

 
Top
Blogger Template