-1

I am new to Javascript.

Below nodejs code runs synchronously, I do not undestand, why?

var http = require("http");
var fs = require("fs");

http.createServer(function (request, response) {

   // Send the HTTP header 
   // HTTP Status: 200 : OK
   // Content Type: text/plain
   response.writeHead(200, {'Content-Type': 'text/plain'});

   // Send the response body as "Hello World"
   response.end('Hello World\n');
}).listen(8081);

// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');

var data = fs.readFileSync('input.txt'); 

console.log(data.toString());   

console.log("Program Ended");

I got output as:

Server running at http://127.0.0.1:8081/
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
Program Ended

Below nodejs code runs asynchronously, I do not understand, why? I agree there is a callback in the readFile function, so why it behaves asynchronously?

var http = require("http");
var fs = require("fs");

http.createServer(function (request, response) {

   // Send the HTTP header 
   // HTTP Status: 200 : OK
   // Content Type: text/plain
   response.writeHead(200, {'Content-Type': 'text/plain'});

   // Send the response body as "Hello World"
   response.end('Hello World\n');
}).listen(8081);

// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');

fs.readFile('input.txt', function(err, data){
    console.log(data.toString());   
}); 

console.log("Program Ended");

Here is the output:

Server running at http://127.0.0.1:8081/
Program Ended
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!

Could you please someone explain me clearly why above is behaving like that. Are callbacks always asynchronous? I also would like to know how execution happens internally for callback functions.

Assume a control came to the line readFile function (which is having callback in it), so why does control immediately executes another statement? If control transers to another statement, who will execute callback function? After callback returns some value, does control again comes back to same statement ie., 'readFile' line?

Sorry for stupid query.

John
  • 55
  • 1
  • 12
  • The obvious answer would be because that's how the `readFile` function is designed. So are you asking why asynchronous versions of their function are needed? –  Apr 23 '17 at 13:29
  • A callback doesn't make asynchronous code run synchronously. It just gives you a way of picking up the flow of execution where you left off. –  Apr 23 '17 at 13:31
  • 1
    Have you noticed that the first example uses readFile**Sync** and the second one uses readFile? One is synchronous the other is not. – Thakkie Apr 23 '17 at 13:32
  • Read the documentation for [readFile](https://nodejs.org/api/fs.html#fs_fs_readfile_file_options_callback) and [readFileSync](https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options) – Santosh Apr 23 '17 at 13:33
  • *"Are callbacks always asynchronous?"* No. Internally the callback is simply invoked like any other function when the internal code has decided it's a good time to invoke it. This doesn't require that there be any async behavior involved. –  Apr 23 '17 at 13:34
  • As an exercise, make a function that receives a callback and executes it. `function foo(callback) { callback("Executing") }` It's really just that simple. No magic, just a function call. So when you call `foo` and pass it a function, it invokes your function. `foo(function(msg) { console.log(msg) })` –  Apr 23 '17 at 13:37
  • Also read this answer: http://stackoverflow.com/questions/19616477/does-javascript-process-using-an-elastic-racetrack-algorithm/19620041#19620041 – slebetman Apr 23 '17 at 14:09

1 Answers1

0

The synchronous version (fs.readFileSync) will block the execution until the file is read and return the result containing the file contents:

var data = fs.readFileSync('input.txt');

This means that the next line of code will not be executed until the file is completely read and the result returned to the data variable.

The asynchronous version on the other (fs.readFile) hand will immediately return the execution to the next line of code (which is console.log("Program Ended");):

fs.readFile('input.txt', function(err, data) {
    // This callback will be executed at a later stage, when
    // the file content is retrieved from disk into the "data" variable
    console.log(data.toString());   
});

Then later, when the file contents is completely read, the passed callback will be invoked and so you see the contents of the file printed at a later stage. The second approach is recommended because you are not blocking the execution of your code during the file I/O operation. This allows you to perform more operations at the same time, while the synchronous version will freeze any other execution until it fully completes (or fails).

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928