10 things you should know about NodeJS

Node.js, at its core, is a highly customizable, stripped-down server engine, as it doesn't do anything out of the box until you set it up. It processes in a loop, ready to respond to requests it accepts. Any of these requests may initiate other requests to another part of the system. This loop, called the event loop, is the "runtime" part. You can snap connectors and libraries such as those relating to SSL, HTTP, filesystem access, compression, and raw TCP and UDP onto the event loop creating a dynamic, simple web server in merely a few lines of JavaScript.

  1. The process of waiting for the queue to synchronously receive a message is named the event loop. The event loop moves in increments, named ‘tick,’ and every time it ‘ticks’ it checks whether the call stack is empty. If it is empty, it executes the top function in the event queue after adding it to the call stack. It starts ticking again once it is finished processing this function.

  2. The Event Loop explains how Node can have non-blocking I/O and be asynchronous. It's two attributes that made it successful. Node.js JavaScript code runs on one thread. Only one thing happens at a time. This is a very helpful limitation, as without having to worry about concurrency issues you can simplify programming. All you need to do is avoid synchronous network calls or infinite loops and pay attention to how you write your code. Basically, anything that could block the thread. In most browsers, in general, for every browser tab, there is an event loop, to avoid a web page with infinite loops and make every process isolated or avoid heavy processing to block your entire browser. Your main concern should be that your code will run on a single event loop. To avoid blocking it, write code with this in mind.

  3. In fact, through the single thread of execution, Javascript is capable of Asynchronous operations. Meaning while an event such as a database request is being performed other events such as a user scrolling or entering data can still be performed. In most other languages, before having to execute any subsequent lines of code, the callback will have to return with its response. This is the reason that promises, Async await, callbacks and others are possible. As in Promises, the ability to assign a state like “waiting” to a function, while performing another event at the same time is why the Event Loop is so powerful.

  4. The library which gives the event loop to Node.js is known as Libuv. Node.js is a platform that's event-based. Meaning, all that happens in Node is a reaction to an event. If a transaction going through Node traverses a cascade of callbacks. This is all handled by a library, now abstracted away from the developer, which provides a mechanism known as an event loop, called libuv.

  5. By default, with four threads to offload asynchronous work to, Libuv creates a thread pool. For many input-output tasks (e.g., AIO on Linux), today’s operating systems already provide asynchronous interfaces. Libuv will use those asynchronous interfaces, whenever possible, to avoid usage of the thread pool. To third party subsystems like databases, the same applies. Here rather than utilizing a thread pool, the authors of the driver will use the asynchronous interface. Basically, the thread pool will be used for asynchronous I/O, only if there is no other way.

  6. The Event Loop essentially works on phases. It goes through a new phase, for each tick of the loop. It maintains a FIFO queue of callbacks for every phase, and in that phase, it executes as many callbacks as it can (on every tick, there is a limit to how many callbacks can be called). The event loop moves to the next phase when the callback limit is reached, or the queue has been exhausted, and so on. Since new events are queued by the kernel after being processed in the poll phase and any of these operations could schedule more operations, while polling events are being processed, poll events can be queued. As a result, the poll phase can be allowed by long-running callbacks to run far longer than a timer's threshold.

  7. Just like in the browser, JavaScript provides a single threaded environment in Node.js. Meaning, no two parts of your application run in parallel. Rather, through the handling of I/O bound operations asynchronously, concurrency is achieved. Any JavaScript code which takes far too much time will block the execution of any JavaScript code in the page as it will take time to return back control to the event loop, and could even block the UI thread, and the user cannot scroll the page, click around, and so on. In JavaScript, almost all the I/O primitives are non-blocking. Filesystem operations, network requests, and so on. And here is why JavaScript is based so much on callbacks, and more recently on async/await and promises, as being blocking is the exception. The fundamental idea is within the front facing Node.js instances, the one which clients concurrently connect to, not to do CPU intensive work.

  8. Since forever, JavaScript has relied on callbacks. Passing, often anonymous, references to functions that act like callbacks are how events in web browsers are handled. Up until promises were introduced, callbacks used to be the only way asynchronous elements of the code in Node.js communicated with each other. Package developers still design their APIs around callbacks as callbacks are still in use. Calling them more than once is a common Node.js issue related to using callbacks. A function provided by a package to do something asynchronously typically is designed to expect a function as its last argument. When the asynchronous task has been completed, this is then called. Of the current function, calling the callback doesn’t just right then end the execution. When the callback they pass is invoked multiple times, anybody using this function from elsewhere may be caught completely off guard. To avoid this Node.js error, all it takes is being careful. Before every callback invocation, some Node.js developers have made a habit of adding a return keyword. The return value has almost no significance in many asynchronous functions, so often, this approach makes it easy to avoid such a problem.

  9. Often referred to as “callback hell,” deeply-nesting callbacks could cause issues making code spin out of control quickly. The worse this can get, the more complex the task. We easily end up with hard to read, error-prone, and hard to maintain code by nesting callbacks in such a way. Declaring these tasks as small functions, and then linking them up is one workaround to this problem. Although, using a utility Node.js package which deals with asynchronous JavaScript patterns is one of the (arguably) cleanest solutions to this.

  10. Asynchronous programming is responsible for the popularity of Node.js and JavaScript with callbacks, although they may not be something unique to them. With other programming languages, we are used to the predictable order of execution, where two statements will execute one after another unless there is an instruction to jump between statements. These are often limited to conditional statements even then, function invocations and loop statements. In JavaScript, however, until the task it is waiting on is finished, a particular function with callbacks may not run well. Until the end without any stop, the execution of the current function will run. Anything needs to be invoked from within it, that needs to happen after a callback has fired.

I hope that some of the concepts explained here will be useful to you in the future.

Need help with product design or development?

Our product development experts are eager to learn more about your project and deliver an experience your customers and stakeholders love.

Read more