Originally written here ->Please have a look.
If you have recently started working with NodeJS you might have heard of blocking and non-blocking code in nodeJS. When I switched from Ruby on Rails to NodeJS, it was one of the concepts that seemed very different to me. Getting directly into writing promises or callbacks is certainly not the right way to go in learning about blocking and non-blocking code in NodeJS.
So, in this article we’ll be taking the simplest of examples of writing to and reading from files in NodeJS and understand how does blocking and non-blocking code work in NodeJS.
Why blocking and non-blocking
We’re not going to go into too much depth in this article about threads and how Node works under the hood but to grasp the concept of blocking and non-blocking code you should know just one thing – Node is single-threaded, i.e, only one process can be run on it at a single time. For example, you write a piece of code for 5 users to interact with, line 8 of your code takes say 2 seconds to execute. If a user A hits line 8 of the code during his process execution and at the same time a user B also tries to execute the same program, that line 8 will be blocking the execution of user B’s program as well.
A piece of code that blocks the execution of any other code beyond it till it itself gets executed is what we refer to as blocking code. This blocking code could be anything – reading from a DB, some complex mathematical operation, some I/O operation, anything.
What is important is to know that blocking code is not good code in NodeJS. We do not want to stall other users for some code someone else is executing. Now, in some super edge case you might specifically want to write blocking code but usually that’s not what we want and what we aim for. Let us now see with this file read-write operation how blocking and non-blocking code works in NodeJS.
The blocking way also called the synchronous way is one in which the code gets executed line by line, ie, the code in the next line will not be executed until the code in the previous line has finished execution.
In this method we use the in-built function of the fs module called readFileSync to read the contents of a file called mytext.txt and store it in the variable called inputText. Later we write that content plus an additional line to a file called outputfile.txt .
The functions readFileSync and writeFileSync as the names suggest are synchronous functions, ie, these are blocking code. What this means is that if the file we are reading is super large and takes 5 seconds then any code ahead of it won’t be executed for those 5 seconds, actually no code in this node process would be executed for those 5 seconds.
See this new code, yeah it’s new 😛 . I have changed the newText that we write here to a different independent of inputText. Now, here we are not dependent on the value of inputText to write to the outputfile.txt . But because this code is blocking, we won’t be able to write before the reading process is over. You can check it by console logging the value of inputText just before the write operation ! It will be present there.
This on the other hand is some non-blocking code. Yes, I’ve used callbacks as those are understood by the majority and even those who still haven’t had exposure to async/await.
In this function, what you’ll notice is that the writing of file outputfile2.txt is completely independent from the execution of the reading of myText.txt. As the function readFile is an asynchronous one, it will not stop the execution of any other code and will quietly keep executing in the background not blocking anything. It is to note that the only code that is waiting to be executed is the one in it’s callback and that is because we need the value of inputText to be set before writing it to outputfile.txt.
In this piece of code if you console log the value of inputText just above the second writeFile, you’ll see it is null. Why ? Because we haven’t waited for the reading to be completed and have directly entered the next line of code.