I'm trying to get my head around synchronous versus asynchronous in Node.js, in particular for reading an HTML file.
In a request handler, the synchronous version that I'm using, which works is the following:
var fs = require("fs"); var filename = "./index.html"; var buf = fs.readFileSync(filename, "utf8"); function start(resp) { resp.writeHead(200, { "Content-type": "text/html" }); resp.write(buf); resp.end(); } exports.start = start;
readFile()
?readFile
is asynchronous so theoretically, I should wait for the entire file to be read before rendering it, so should I introduce an addListener
? I might be confusing different things.Edit: I have tried to refactor the code like this:
var fs = require("fs"); var filename = "./index.html"; function start (resp) { resp.writeHead(200, { "Content-Type": "text/html" }); fs.readFile(filename, "utf8", function (err, data) { if (err) throw err; resp.write(data); }); resp.end(); }
I get a blank page. I guess it's because it should wait for all the data to be read, before resp.write(data)
, how do I signal this?
In fs. readFile() method, we can read a file in a non-blocking asynchronous way, but in fs. readFileSync() method, we can read files in a synchronous way, i.e. we are telling node.
Syntax: fsPromises.readFile( path, options ) Parameters: The method accept two parameters as mentioned above and described below: path: It holds the name of the file to read or the entire path if stored at other location. It is a string, buffer, URL or a filename.
It starts reading the file and simultaneously executes the code. The function will be called once the file has been read meanwhile the 'readFile called' statement is printed then the contents of the file are printed.
The default encoding is utf8 and default flag is "r". callback: A function with two parameters err and fd. This will get called when readFile operation completes.
var fs = require("fs"); var filename = "./index.html"; function start(resp) { resp.writeHead(200, { "Content-Type": "text/html" }); fs.readFile(filename, "utf8", function(err, data) { if (err) throw err; resp.write(data); resp.end(); }); }
This variant is better because you could not know whether file exists or not. You should send correct header when you know for certain that you can read contents of your file. Also, if you have branches of code that does not finish with '.end()', browser will wait until it get them. In other words, your browser will wait a long time.
var fs = require("fs"); var filename = "./index.html"; function start(resp) { fs.readFile(filename, "utf8", function(err, data) { if (err) { // may be filename does not exists? resp.writeHead(404, { 'Content-Type' : 'text/html' }); // log this error into browser resp.write(err.toString()); resp.end(); } else { resp.writeHead(200, { "Content-Type": "text/html" }); resp.write(data.toString()); resp.end(); } }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With