Imagine you’re jonesing for a nice iced mocha at work. You decide to take a little jaunt to your local neighborhood cafe or Starbucks and notice there’s a line going around the block! Actually, around several blocks!
You wonder if it’s some grand reopening or remodeling going on which is causing the giant line. Or maybe some 2 for 1 discount that is causing a lot of customer frenzy?
But you don’t notice any special banners or signs at the store that usually advertise those kinds of special events. And the customers in the line don’t appear particular jazzed or excited to be in line. There are no balloons or party favors either.
You look around and you don’t see any other coffee shops around, and you’re really dying for an iced coffee. You shrug and you decide to wait at the end of the line. After all, if the line is as huge as it is, the coffee must be to die for there, right??
And so it goes….
And TWO HOURS LATER, after you’ve checked your Facebook, LinkedIn, Twitter and Snapchat accounts ten times over, and gotten a new high score in Angry Birds on your smartphone, you finally get to the beginning of the line. Your tongue is parched like a desert and all you can think about is that sweet ice cold beverage going down your threat.
The anticipation has been building up in your head the whole time you’ve been waiting. This must be the greatest coffee shop in the universe, if it takes two whole hours to get your coffee order!
When you finally reach the beginning of the line, it suddenly becomes clear why it took a godawful amount of time to move through the near endless line.
You belly up to the order counter and tell the barista you want an iced coffee. The barista takes down your order, rings it up, and tells you the total. You fish the money out of your wallet and pay up.
You look around the shop for the pick-up orders area … and you realize there isn’t any.
You ask the barista where you’re supposed to pick up the order and they say that there is not pick up order.
The barista who just took your order and processed your payment is now making your coffee order!
You look around behind the counter and with a horrifying sense of understanding, you realize why it took two hours to get through the line to get your order.
In technical-ese, the coffee shop is running SYNCHRONOUSLY.
ONE PERSON is taking your order, ringing it up on the cash register, making the actual coffee, and notifying you once the coffee order is ready for you to take.
And all this time, the customer line is backing up around the city block because of this business structure.
Believe it or not, that is essentially how most (until the advent of NodeJS) web applications work.
A traditional web server like Apache or Microsoft IIS is pretty much like that single employee barista taking your order (essentially your http request when you visit a certain web page). That web server will take your request, process it, and ultimately serve your order back (which is the web page you originally wanted).
The reason why a web server can handle many concurrent http requests is because it “spawns” many little digital baristas (threads) to process each unique request.
But the catch is that when more and more customers hit that same web server, the more threads the web server has to spawn. Each individual thread takes up resources (computer memory) and if you tax the web server enough, you eventually hit a threshold and any new customers trying to reach the web server will either get very slow response times or no response at all.
You have to either allocate more memory to the web server, or add more web servers and/or computers to handle the load. If you’ve heard of the term, “web farm”, it’s pretty much exactly what it sounds like … a digital “farm” of computer servers that do their part to handle an army of web requests.
And for many years, that was the way web application architecture worked.
But with the advent of NodeJS, a new type of web application framework, web applications act and behave much more like how a real world coffee shop works.
Imagine the same coffee shop that we talked about before.
But now imagine that as you walk to the coffee shop, the customer line is very short and moving along at a very brisk pace.
Only a few seconds after you enter the shop, it’s already your turn to make an order!
The employee at the cash register takes your order and then gives you an order number and then asks you to walk to the order pick up section of the shop. The next customer standing behind you is already placing their order.
You notice that there are other employees solely responsible for handling the actual process of making customer orders. And the employee at the cash register is always at the cash register processing orders.
And when you order is ready, you hear an employee “call back” to you with your order number that your coffee order is ready to be picked up.
Because the person taking your order and processing your payment is a different employee than the person making your coffee and notifying you that your order is ready to be picked up, your total wait time from the time you entered the coffee shop to the time you picked up your order is DRASTICALLY shorter than before.
In technical-ese, this type of processing is called ASYNCHRONOUS processing.
Handling requests asynchronously allows you to handle many more incoming requests simultaneously AND at a much more scaleable level than SYNCHRONOUS web frameworks.
Newer web frameworks like NodeJS handle requests in a very similar way to the way coffee shops like Starbucks handle coffee orders in the real world.
In NodeJS code, you will typically see code like this to handle web requests:
var express = require(‘express’);
var router = express.Router();
/* GET home page. */
router.get(‘/’, function(req, res, next) {
res.render(‘index’, { title: ‘Express’ });
});
module.exports = router;
Most code in the NodeJS framework is designed to work ASYNCHRONOUSLY.
Imagine firing up a web browser to get to a certain website written in NodeJS.
It’s like going to the coffee shop and walking up to the cash register to place a coffee order.
Behind the scenes, another coffee shop employee is busy processing your coffee order.
When the coffee order is done and ready to be picked up, you get a “callback” saying, “Order #123 is ready!”
In the same way, the NodeJS code has a “callback” function that runs when your web request is ready to be processed.
The code inside the router.get() function runs when the NodeJS framework is ready to handle your initial http request you made when you fired up your web browser and typed in the web address of the website you wanted to visit.
It’s one of the reasons why NodeJS is fast becoming the go to web framework for companies that required vastly scaleable and fast performance for millions and millions of concurrent web requests.
Some of the biggest companies on the web are using NodeJS including Netflix, the New York Times, Paypal, LinkedIn and Uber, and it’s easy to see why once you understand the advantages of asynchronous processing.