JavaScript's Event Loop
Tags: javascript, node, threading
Published: 2020-05-23 08:56:37

---
title: JavaScript's Event Loop
published: true
description: Where it comes from and why it is needed in NodeJS
tags: javascript,node,threading,nodejs
---

## TL;DR

NodeJS uses an event loop (essentially a while loop) to run concurrent processes, for a smooth experience. This design is due to JavaScript and DOM operations being _single-threaded_. While others languages typically use multi-threading instead to achieve concurrency. 

This single-threaded approach scales well in certain cases like for non-blocking UI or when thousands of threads incurs a cost of switching threads.

_UPDATE: I originally thought the single-threaded approach was a limitation of Node and JS which prevents scaling, but it can be strength (see comment discussion), so I've updated this article._

## The origin of NodeJS and the need for concurrency

I heard that NodeJS was created because JavaScript was the _only_ language with an **event loop**. 

JavaScript (or ECMAScript) was built for the browser /then repurposed to run **server-side** scripts applications under the NodeNS runtime environment. And Node that was built on event-driven programming to allow asynchronous tasks. This means concurrent processing can handle **non-blocking tasks** smoothly -- such as to fetch data while rendering UI and also checking for mouse-based events to fire.

Node achieves this through what is known as the _event loop_. The concurrency page on the Mozilla docs has an Event Loop section which says that it is usually implemented using a `while` loop which continously checks for events to fire.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

The top of that page explains that this is _not_ typical of concurrency other languages, like **C** or **Java**. These do _not_ have the single-threaded limitation of JS and so use multi-threading instead of an event loop.

## NodeJS and the event loop

In this **talk** by the Node creator, he explains in the first minute that the event loop (from the browser side) turned out to be _necessary_ for the success of Node.

- https://youtu.be/M3BM9TB-8yA

This is necessary because Node is _single-threaded_:

- https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop

> _The event loop is what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible._

And the reason Node is _single-threaded_ is because JavaScript has to run in the browser as single-threaded -- since parallel operations on the DOM tree are not safe. See below.

- https://www.red-gate.com/simple-talk/dotnet/asp-net/javascript-single-threaded/

> _Why then shouldn’t we just handle all the events we are subscribed to in old-fashioned parallel way? The reason is that we don’t want to change the DOM in parallel: this is because the DOM tree is not thread-safe and it would be a mess if we tried to do it. Because of this limitation, all our JavaScript code should be executed in single thread, while at the same time ensuring that it handles all the events and doesn’t lose any callback._

Follow the articles above for more detail on the event loop.

UPDATE: I found this series where the first article has some neat animations on the event loop - [check it out](https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif).

## More details on concurrency in other languages

Apache and Ruby using multiple threads but are inefficient at scale - see [comment](https://dev.to/koresar/comment/1310a) below.

**Python** has the [threading](https://realpython.com/intro-to-python-threading/) library as well as [multithreading](https://docs.python.org/3/library/multiprocessing.html) library for multi-core processing. 

Threading in **[Elixir](https://medium.com/flatiron-labs/elixir-and-the-beam-how-concurrency-really-works-3cc151cddd61)** is supposed to be a great strength for handling millions of requests efficiently.

New languages like **Go** and **Rust** can be very efficient at high-performance computing for modern computing tasks - in particular concurrent tasks that would be much slower in older languages. 

Go was designed from the start to be fast to develop, fast and to handle concurrency with a "goroutine". See [concurrency](https://tour.golang.org/concurrency/1) in the docs and an example of [goroutines](https://gobyexample.com/goroutines).