Callbacks In Node Js Bootcamp

From 30 Minute Missions: Wargame

Callbacks in Node.js Bootcamp
In this part we will discuss Event loop in Nodejs, callbacks in Node.js and NPM modules(Node Package Manager. We will try to ascertain why asynchronous callbacks is the key mechanism behind the nodejs architecture and its advantages over synchronous callbacks.





Event loop in Node.js
Event loop in Node.js are what allow JavaScript to perform non-blocking I/O operations. In fact, JavaScript is single threaded, which means that once an application has begun running, others cannot be executed until the previous operation is completed.

Kernels today come with built-in support for multi-threading. Often, multiple operations are executing in the background at the same time. When one of these operations is completed, the kernel can notify the JavaScript library, Node.js, so that the appropriate callback can be added to the poll queue that will eventually be dispatched to the appropriate callback.

There are 2 types or ways of programming in node.js which are

Synchronous Callbacks and

Asynchronous Callbacks

Callbacks in Node.js
When defining the key components which is callbacks in Node.js, the syntax offers a prohibition. In other words, the semantics of a callback function are always synchronous. Callbacks is the mechanism in which the program has to call the specific function after completion of a give set of instructions or the given set of code blocks containing the logic. Synchronous callbacks can block the event loop and restrict the server scalability. All methods functions in Node.js are written in such a way that they support callbacks.

Synchronous Callbacks in node.js
Synchronous Callbacks in node.js is a blocking call, where the thread is blocked to execute the functions in a synchronous way and the rest of the program execution needs to wait until the current function gives its result or until that call is over.

Asynchronous Callbacks in node.js
Asynchronous Callbacks in node.js is a non-blocking call, where the thread continues to execute the rest of the program, while the call/current function is executed separately the thread doesn’t needs to wait for the current function’s result in order to execute the next functions inside that thread.

A sample illustration to demonstrate Synchronous Callbacks in node.js

function getCallbackSync(callback)
callback("This is the first call");

console.log("Before displaying the first call");

getCallbackSync(function(display)
console.log(display);
);
console.log("After displaying the first call")
The output for the above code is:

> Before displaying the first call
> This is the first call
> After displaying the first call
At first we declared a function getCallbackSync with an argument named as "callback"

That argument will display the message "This is the first call" into the console.

Then we wrote a console log function(which is a core module) that will display the message "Before displaying the first call"

Then we simply tried to implement/call the getCallbackSync function to execute its output which takes in an argument named "display" and write the value which it receives by calling the "getCallbackSync" function. Then in console log function it will display the message "This is the first call"

Here we are calling the "getCallbackSync" function as a Synchronous Callback.

In order to call a function first we write its name which is ""getCallbackSync" in line 6 then inside the ( parentheses we start by providing an argument for the function which we do by (function(display).

After that we go inside the opening braces , in line 7 we write console log which will output the result which it receives by calling the "getCallbackSync" function. As per line 1

Remember that inside the "getCallbackSync" As per line 1 we passed the argument of the callback as "This is the first call", (in line 2, we pass an argument to the function inside a parentheses), this is then accepted as the argument when "getCallbackSync" in line 6 is called, and then the "display" parameter takes in the argument "This is the first call", which after that outputs in the console.

After that we wrote another console log function that will display the message "After displaying the first call".

So here at first "Before displaying the first call" will be printed on screen. As per line 4( since we only declared the function from line 1 to 3 it will be called when we call this function in line 6)

Then the program reaches line 6 and calls the "getCallbackSync" function which in turn prints the message "This is the first call". Here we should take note that the lines below the function call which is from line 9, the thread will stop executing itself until the "getCallbackSync" is executed completely which simply means that if there is a large program and large set of instructions which are waiting after and onwards line 9 all of them will get stuck until the "getCallbackSync" function finishes printing the message.

In this case we only had 1 line to be called which was 9th line which needs to display the message "After displaying the first call" into the console.

Consider a real world application when suppose the function in line 6 needs to perform a database query or a search operation in the database, the code after this function call will have to stop until the database query is finished which is the disadvantage of the Synchronous Callbacks in node.js.

This disadvantage is removed by the Non Blocking Asynchronous Callbacks where the rest of the code doesn’t needs to wait until the current function is executed. In other words line 9 does not need to wait until the function call in line 6 completes its task, or a program doesn’t needs to mandatorily wait for the database search operation or query operation to finish itself before executing next lines of the program.

This capability of node.js allows itself to write a highly scalable and realtime backend server.

To demonstrate this Non Blocking or the Asynchronous Callbacks consider the same program example we took earlier but this time let us make the getCallbackSync function to wait for 5000ms or 5 seconds before executing the next instruction.

function getCallbackSync(callback)
setTimeout(function () callback("This is the first call") , 5000);

console.log("Before displaying the first call");

getCallbackSync(function(display)
console.log(display);
);
console.log("After displaying the first call");
This will print –

> Before displaying the first call
> After displaying the first call
> This is the first call
Note that this time the line 9 which was to print "After displaying the first call" did not waited for 5 seconds in order to finish let the function "getCallbackSync" finish itself first.

In other words consider if there was a database operation that was needed to be performed in the function "getCallbackSync" which is suppose to be taking 5 seconds of time, the next instructions in after this function needs not to mandatorily wait for 5 seconds or whatever time it takes. Suppose in a real world example we are watching a TV show in Netflix which is currently showing a video, if we want to simultaneously open another tab and do some other work in Netflix like update our email or update our payment method or to raise a support ticket, all of these tasks doesn’t need the video to be finished first or it doesn’t needs us to close the video first in the previous tab and then perform these tasks.

So while viewing the event loop if we use synchronous callbacks they will block the whole event loop where as asynchronous callbacks allow the program to offload or distribute its works to the kernel and work in parallel manner. In our example where we made the function to wait for 5 seconds, this function was immediately offloaded to kernel to be processed in parallel with the next instructions of the program to be allowed to execute immediately and doesn’t needs the kernel to finish that 5 seconds operation first.

In the image shown above there are multiple asynchronous callback functions in which there are 3 asynchronous functions that need to be performed but due to being asynchronous in nature it offloads all of the three functions to the operating system’s kernel processes and continues with the next set of instructions will instruction 2, 4, 5 being processed in separate processes in parallel to the rest of the nodejs code. As soon as any of the instruction comes out with their respective outputs they are then finished accordingly. Note that this image is different from the term callback hell, and we will discuss about it in next section, this is different in a way that instructions 2,4,5 are separate callback functions and does not gives rise to another callback/child callbacks within themselves which is nested callbacks(a callback itself containing multiple callbacks, in our example if we put another set timeout function inside the 5 seconds timeout function then this is called nested callbacks/callback hell. Suppose we have another 8 seconds callback inside the 5 seconds and the 8 seconds one further has a callback for say 3 seconds it is termed as nested callbacks/callback hell which we will discuss in the next section and how to avoid writing such kind of instruction sets in our program).

NPM modules
NPM modules or NPM (Node Package Manager) is the utility which ultimately allows the developer to package their project into a so-called Module, such as JSON, HTML, Markdown and so on. These modules will form a library which can be imported into any other modules.

Node.js modules are like blocks of code that are used in node.js (a framework that’s used to build web applications). They are used to organize logic that needs to be reused. And normally most programmers find modules are easy to understand and the best way to program (reduce the complexity of code into smaller pieces).

In Nodejs, there are 3 types of modules, 1. A. Common functions used by other modules Types of Modules:

Core Modules – A comprehensive and robust set of technology, libraries, and tools will help you to write professional and powerful websites. It is what makes you go faster (e.g., hyperloading).

Core Modules: Node.js comes with dozens of built-in modules. These module are built around the require() function. require() is a special syntactic function, which allows you to load a module in JavaScript, which you use like Java does ‘import’. Modules you include use require() to import their contents.

Local Modules – You would be ill-advised to simply place code in all your files. As you add more code, you will want to preserve logical coherence, and break your code into a multitude of files. For that purpose, we can create local modules of our web app.

Third-Party Modules – Modules can be installed from NPM’s interactive interface.

NPM in Node.js

NPM in Node.js stands for "Node Package Manager". It is a default package manager for Node.js and runs completely in Javascript. NPM manages all of the dependencies and modules. By installing Node.js, NPM is added to the operating system. We can install, manage, update and remove the Core Modules, Local Modules and Third-Party Modules via the Node Package Manager

Policies dictate which required modules are installed at the package level. Packages include all of the files that are required for the included module. These packages are mostly JavaScript libraries that serve as excellent tools for Node.js applications. Included packages often speed up application development through the inclusion of excellent tools.

NPM is responsible for installing most of a project’s dependencies via modules. It has the ability to upgrade and remove modules. The modules of each dependency may specify a range of valid versions as outlined by semantic versioning. This permits developers to auto-update their modules without causing unwanted breaking changes.

Remembering our previous article about running a hello world program we installed the http module which is one of the core modules and we did it with the NPM package manager via the command prompt/terminal for Mac. We also installed node.js all the mandatory core modules by running the command "npm init", we then installed the http module by this command "npm i —save http"