In this example, first, the file system module is required, then, the file is read, and then, we log the result to the console. So, each line of code basically waits for the result of the previous line.
Now, this can become a problem, especially with slow operations, because each line blocks the execution of the rest of the code. So, synchronous code is also called blocking code because a certain operation can be only executed after the one before has finished.
So, the solution to this problem in Node is to use asynchronous, non-blocking code. So, in asynchronous code we offload heavy work to basically be worked on in the background. Then, once that work is done a callback function that we register before is called to handle the result. During all that time, the rest of the code can still be executing without being blocked by the heavy task, which is now running in the background. So, what this means is that we can effectively defer or reaction into the future in order to make the code non-blocking.
So, in this example, the readFile() accepts a callback function. This will start reading the file in the background and then immediately move on to the next statement printing to the console the string-reading file. Then, when the file is finally completely read, the callback function will be called, and so, the data that was read will then be printed to the console.
A Node JS processed, which is where our application is running, there is only one single thread. And the thread is like a set of instructions that is run in the computer’s CPU. So, basically the thread is where our code is actually executed in a machine’s processor. So, for each application there is only one thread. So, all the users accessing your application are all using the same thread, so basically, accessing the same thread. So, whenever they are interacting with the application, the code that is run for each user will be executed all in the same thread at the same place in the computer running the application. When one user blocks the single thread with synchronous code, then all other users will have to wait for that execution to finish. That might not be a huge problem if you have 5 users, but it definitely will for thousands or millions of users at the same time.
So, if there is a user accessing your application and there is huge synchronous file read in your code that will take one second to load that means for that one second all other users will have to wait because the entire execution is blocked for that one second. So, if the other users want to do some simple task like logging into your application or just requesting some data, they will not be able to do so. They will have to wait until the file is finished reading. Only when that happens they will finally be able to perform the simpler tasks, one after another. This is what would play out with synchronous blocking-code, which is obviously a terrible experience for your users.