Algobook
- The developer's handbook
mode-switch
back-button
Buy Me A Coffee
Wed Aug 09 2023

The event loop in JavaScript

Have you ever wondered how a single threaded language like JavaScript allows you to perform a lot of executions while it is firing away a request to an external API? Or how the good old "setTimeout" function works? Maybe you've been scratching your head and spent sleepless nights asking yourself, how on earth can I click on buttons and scrolling while other parts of my code is running?

Well, let me introduce you to the core of JavaScript and how it operates in the background, with the help of the event loop.

Background

As stated, the JavaScript language is a single threaded language. Which means, that there will only be a main thread that will execute the code. Unlike other languages, like Java or C# which supports multithreading to execute the program. The approach may sound a bit weird at first, since having only a single thread may cause issues such as blocking code executions and I/O actions as it may be performing another task at the same time. And since JavaScript can only do one task at the time, this should be troublesome. However, using built in techniques and knowing how the event loop operates, the single threaded approach will be a non-issue.

The event loop contains three main parts.

  • Stack
  • Queue
  • Heap

Stack

Let us start with the stack. The stack contains a list of operations, such as function calls. When a function is called in the code, a frame will be added to the stack. When another function is called, it will be placed on top of the previous frame and so on. And then the frames (actions) will be called from the top to bottom, and once they are executed, they will be removed from the stack.

Example of frames in the stack

Let's visualize the behaviour of the stack. We will have three functions, where each function will call another function inside of it.

function a() { // some logic } function b() { a(); } function main() { b(); } main();

So what is happening here, is that we have our 3 functions, where our main function will call the b function which will in its turn call the a function. The frames will be added in this fashion: main, b and a where a will be at the top and executed first.

Example of the stack:

a b main

Heap

The heap in JavaScript are used as memory allocation. The heap will contain objects and functions that it will store for reference. So when an object are referenced, it will be stored in the heap.

class Animal { name; } const tiger = new Animal();

In above example, the tiger object will be stored in the heap.

const anotherTiger = tiger;

By using the above approach, our anotherTiger variable will point to the same reference as tiger, hence they will both be affected by their respective changes. Meaning, doing something like this

tiger.name = "Tony"; console.log(anotherTiger.name); // Tony

is a very common mistake that will cause unwanted behaviour in larger applications.

Garbage collecting

In order for JavaScript to keep the memory as slim as possible, it will use garbage collecting, just as many other languages. The idea behind this, is that when objects and functions are no longer referenced, they will be released from the heap. JavaScript are using the mark-and-sweep algorithm for their garbage collecting, which basically checks from the root and down, to see if any object is not being referenced anymore, and if not, it will be released.

The garbage collecting is an automatic process, and cannot be manually triggered. And a drawback of the mark-and-sweep algorithm is that the objects in the heap needs to be explicity unreachable in order for the algorithm to pick it up and release it.

Queue

During runtime, messages that are listed inside of the queue are being processed. A message are typically a callback, hence, the queue is often referred as the callback queue. When the frames are empty in the stack, the functions associated with the callback are being placed in the stack as new frames for processing.

A general example for demonstrating the queue in action, is by using setTimeout. I will do the same thing in following snippet, to demonstrate how it could work.

Consider below code. We will do three logs to the console, where one of them are being placed in a setTimeout with the delay set to 0 (default).

console.log("1"); setTimeout(() => { console.log("2"); }); console.log("3");

In this example, our stack will get the two console.log functions frames and the queue will get a message with the callback function that are calling our console.log("2") action. The event loop will process the two frames first, and then move on to the queue and add the callback function to the stack afterwards. This will result in an output as follows:

1 3 2

This approach where used as hacks, and perhaps still are, when developers encountered issues with functions that were suppose to run after the DOM was loaded properly ran prematurely - hence, adding the functions as callbacks to a setTimeout with delay of 0 would solve their issue since it would be processed after the DOM was properly loaded. But since frameworks such as React took over more and more, these situations are quite rare I would say.

Outro

In this article, I shared how the event loop works in JavaScript, and showed some examples to demonstrate the event loop in action, in its simplest form. It is very beneficial as a JavaScript developer to really grasp the concept of the event loop, since it gives a clear image of how things are actually working in the background. It will also provide a great understanding on how objects and functions are referenced and how they can both help (or overthrow, if not being cautious) you when writing your code.

I hope you enjoyed this one!

More on the event loop

More on memory management

signatureWed Aug 09 2023
See all our articles