Intro to Node.js: What Makes It Different?
Jamison Prianos, Accusoft Software Development Manager, SaaS
This is the third post in our introductory series on Node.js. If this is the first post you’ve found, be sure to check out Part 1: What Makes Node So Popular? and Part 2: There’s a Module for That! Today, we’re moving on to discuss what makes Node.js different and when you really shouldn’t use it.
After what you’ve seen so far of our introduction to Node.js, you may be wondering, what makes Node different from most other systems? There are a lot of single-threaded models out there, but most of what we work in if we’re coming from C#, PHP, Prefork, or Java, is going to be a multi-threaded environment that’s blocking. With Node, everything in your application executes on a single processing thread. So while behind the scenes the v8 engine is all kinds of complex and C++ multi-threaded goodness, your application runs in a single thread that is non-blocking and works off events that get fired.
Below, we’ll talk a little bit more about what that means for your applications.
Applications Executing on a Single Thread
With Node, when you have something that is waiting for File I/O, a network response, or some controller to return from a physical device that you’re connected to, it’s not going to hold up processing of the application. You don’t have to spin off a new thread in order to wait for something to stop blocking. You simply give the thing that you’re making a call to an opportunity to respond by giving it a call back or some other mechanism. Basically, you say, I’m going to let the application continue to run, and when you’re done, you come back to the stack and say you’re ready to run. Then you’ll get put at the end of the list and be allowed to execute.
This way we don’t have to wait for a return. We can just keep going with our code and let things happen asynchronously. That is probably one of the most useful and important pieces of Node. This is also one of the biggest stumbling blocks for people new to Node—when they try to read the code top down, and it almost never works that way in Node. Your code will never be top down.
The general idea is to allow lots of different pieces to operate on one thread without blocking each other. For those who have worked with Apache or NGINX, you know that if you have a single thread in those systems, it would basically be unusable because if one person is making a request while that file loaded, we would not be able to answer requests from other people. With Node, your server can have a request, do some I/O, and when another request comes in, it can grab that event process. This allows for thousands of active events going on at any given time.
When Should You Not Use Node?
There are plenty of good reasons to use Node.js. There’s also one very, very, very good reason not to use it. If you’re building a CPU-intensive application, it’s best not to use Node because it is all intended to run in a single thread and not be blocking. So, if you are doing something that can take 10 seconds of fully focused CPU time that’s not waiting, that is ten seconds where your application is completely deadlocked. Node is not meant for that. It is not as performant for heavy processing as lower-level options such as C++. The library, the language, and the runtime were built around the whole idea that you’re going to be doing a small bit of processing and then waiting for someone else. That could be waiting for a person or a web response, but most of the time you spend is spent not doing anything.
Jamison Prianos is a Software Development Manager in the SaaS division of Accusoft Corporation. In addition to coordinating engineering efforts for his teams, Jamison acts as an evangelist for solid Node development patterns and specifically microservices both within and outside of Accusoft, while also holding on to actual development work for dear life.