w3resource logo


node.js Tutorial

Node.js Programming Model

Secondary Nav

Introduction

Over years many developers have tried to reintroduce JavaScript as a server-side language. In JSConf 2009, Ryan Dahl introduced Node.js, a server side language, based on v8. Since then, it shaw an exponential proliferation among developers. In this tutorial, we will discuss the fundamental programming constructs followed by the Language.

JavaScript and Node by extension are single threaded and Node uses non-blocking I/O and an asynchronous event-driven model. Never blocking on I/O means less thread. It is quite similar to Ruby’s Event Machine or Python’s Twisted, but Node presents the event loop as a language construct instead of as a library. In this tutorial, we have discussed two important programming model asynchronous model and Callbacks. Later we will discuss another core model Event-emitters

Asynchronous model

Let's discuss the Asynchronous model with a simple use case. You must have seen advertisements (or similar third party content) load in a web page sometimes cause more latency. If they are loaded asynchronously, they will not block loading other constituents of the webpage (e.g. content). This will improve user experience and optimized use of bandwidth, particularly for mobile users, which constitute a large chunk of internet viewers nowadays.

Node is non-blocking which means it can take many requests at once. In Node programming model almost everything is done asynchronously but many of the functions in Node.js core have both synchronous and asynchronous versions. Under most situation, we should use the asynchronous functions to get the advantages of Node.js. Here is an example comparing synchronous and asynchronously model using file_system.readFile

Example : Synchronously reads the file

Here we have used fs.readFileSync() which is the synchronous version of fs.readFile(). It also returns the contents of the filename.

var fs = require('fs');
var content = fs.readFileSync("readme.txt", "utf8"); console.log(content); console.log('Reading file...');
Output :

nodejs synchronously reading a file

Example : Asynchronously reads the file

var fs = require('fs');
fs.readFile("readme.txt", "utf8", function(err, content) {
if (err) {
      return console.log(err);
	     }
  console.log(content);
      });
console.log('Reading file...');

Output :

nodejs asynchronously reading a file

The first block of code looks simple, readFileSync() will read the entire file and store it into the memory and then go to print the data and a message in the console (see the output). This is the synchronous version, everything is paused until the file is finished reading. However, the second block of code is the asynchronous version but looks complicated. Here the system is ready for performing another task - instead, the callback function gets called when the file is finished reading. See the output, it first executes the last command and prints "Reading file..." then it prints the contents of the file.

Callbacks

What are callbacks? A callback function is a function that is passed to another function as a parameter, and the callback function is called (executed) inside the second function. Callbacks functions execute asynchronously, instead of reading top to bottom procedurally. If you have already worked with JavaScript  then there is a chance you've seen callbacks already. This is an important topic to understand how Node.js server works. For example, we are trying to download a large file and we don't want that server blocks all other request to complete the download job, rather we want to send this download job in the background and to call a function when it's finished. Therefore server should follow the second rule and can accept other request while it is doing something in the background and makes other code non-blocking.

In a synchronous program, you can write codes in the following way :

var content;
function readingfile() {
var fs = require('fs');
content = fs.readFileSync("readme.txt", "utf8");
return content;
}
readingfile();
console.log(content);

In the above code block we have defined a function called readingfile() who's task is to read a file and store it's content to a variable. When the function is called, if reading data takes a long time to load the data, then this cause the whole program to 'block' - otherwise known as sitting still and waiting. This is the expectation of synchronous code - it sequentially runs top to bottom.

Node.js uses callbacks, being an asynchronous platform, it does not wait around like database query, file I/O to complete. The callback function is called at the completion of a given task; this prevents any blocking, and allows other code to be run in the meantime. See the following example :

var fs = require('fs');
var fcontent ;
function readingfile(callback){
fs.readFile("readme.txt", "utf8", function(err, content) {
fcontent=content;
 if (err) 
 {
 return console.error(err.stack);
  }
callback(content);
})
};
function mycontent() {
  console.log(fcontent);
}
readingfile(mycontent);
console.log('Reading files....');

In the above example the mycontent() function can get passed in an argument that will become the callback variable inside the readingfile() function. After file reading is completed through readFile() the callback variable ( callback()) will be invocked. Only function can be invoked, so passing anything other than function will cause an error. When a function gets invoked, the code inside that function get executed ( here console.log(fcontent) statement will execute).

At first glace, the above code looks unnecessary complicated, but callback is the foundation of Node.js. This allows you to have as many I/O operations as your OS can handle happening at the same time. For example, suppose in a web server there are hundreds or thousands of pending requests with multiple blocking queries, but performing the blocking queries asynchronously gives you the ability to work continuously and not just sit still and wait until the blocking operations come back.

In the above environment, generally, the callback is the last parameter and error value is the first parameter of the callback.The callback gets called after the function is done with all of its operations. If any error occurs the function call the callback with the first parameter being an error object otherwise (in the case of clear execution) the function call the callback with the first parameter being null and the rest being the return value(s).



Join our Question Answer community to learn and share your programming knowledge.