Chapter 3. Building Robust Node Applications
The Event Loop
A fundamental part of Node is the event loop, a concept underlying the behavior of JavaScript as
well as most other interactive systems.
Why does this make Node more efficient? Imagine ordering food at a fast food restaurant. When
you get in line at the counter the server taking your order can behave in two ways. One of them is
event driven and one of them isn’t. Let’s start with the typical approach taken by PHP and many
other web platforms. When you ask the server for your order, he takes it but won’t serve any
other customers until he has completed your order. There are a few things he can do after he’s
typed in your order: process your payment, pour your drink and so on. However the server is still
going to have to wait an unknown amount of time for the kitchen to make your burger (to one of
the authors, who is vegetarian, orders always seems to takes ages). If, as in the traditional
approach of web application frameworks, each server (thread) is allocated to just one request at
a time, the only way to scale up is to add more threads. However, it’s also very obvious that our
server isn’t being very efficient. He’s spending a lot of time waiting for the kitchen to cook the
food.
Obviously, in real life restaurants use a much more efficient model. When a server has finished
taking your order, you receive a number which they can use to call you back. You could say a
call-back number. This is how Node works. When slow things like I/O start, Node simply gives
them a callback reference and then gets on with other work that is ready now, like the next
customer (or event in Node’s case). It’s important to note that as we saw in the example of the
postman at no time does a restaurant server ever deal with two customers at the same time.
When they are calling someone back to collect an order they are not taking a new one and vice
versa. By acting in an event-driven way, the servers are able to maximize their throughput.
Another interesting thing this analogy illustrates is cases where Node fits well and where it
doesn’t fit. In a small restaurant where the kitchen staff and the wait staff are the same people,
no tradeoff can be made by event-driven. Since all the work is being done by the same people
event-driven architectures don’t add anything. If all (or most of) the working your server does is
computation, Node might not be the ideal model.
However, we can also see when the architecture fits. Image there are two servers and new four
customers in a restaurant. If the servers serve only one customer at a time, the first two
customers will get the fastest possible order, but the third and forth customers will get a terrible
experience. The first two customers will get terrible experience. The first two customers will get
their food as soon as it is ready because the servers have dedicated their whole attention to
fulfilling their order. That comes at the cost of the other two customers. In an event driven model,
the first two customers might have to wait a short amount of time for the servers to finish taking
the orders of the third and forth customers before they got their food, but the average wait time
(latency) of the system will be much much lower.
Let’s consider some numbers. When we run an operation in the CPU (not a line of JavaScript but
a single machine code operation), it takes about 1/3 of a nano second. A 3GHz processor runs