Cover image for JS illustrated: The event loop ๐Ÿ”

JS illustrated: The event loop ๐Ÿ”

kapantzak profile image John Kapantzakis ใƒป3 min read

Javascript is single threaded, yet, developers can write asynchronous code in Javascript!

But how is it possible? The event loop makes it possible!

Before we start, lets define the environment in which the event loop operates. We assume that we are dealing with Javascript code that is executed by a browser (not in Node or other environment).

Lets meet the heros of our story

The call stack

Alt Text

The call stack is a place in memory that keeps track of the function executing at that time, and the functions that are going to be executed after that. Each function is placed on top of the previous function. The first function added, is going to be executed last (First in, last out).

The web API

Alt Text

The web API is not part of the core JS, instead, it provides various methods that can be used by a Javascript program, like setTimeout() or alert().

The message queue

Alt Text

The message queue is a list of messages, waiting to be executed by their associated functions. A new message is added to the list, each time an event, that has been watched by an event listener, occures.

The event loop

Alt Text

The event loop is a process that keeps running and checks whether the call stack is empty or not. If the call stack is empty, it pushes the first item of the message queue into the call stack for execution.

Here's the browser environment

Alt Text

A JS story

Lets take a look at the following code and see what happens

Calling the foo function, the result is

> One
> Three
> Two

Now, lets see our heros trying to execute the above code

First, the browser sends the foo() function call to the call stack.

Alt Text

The console.log("One") statement gets pushed on top of the previous frame.

Alt Text

In the meanwhile, the event loop checks to see if the call stack is empty

Alt Text

The JS runtime executes the top frame and removes it from the call stack.

Alt Text

Continuing the execution, the browser sends the setTimeout() statement to the stack

Alt Text

The event loop checks again

Alt Text

The environment sets up a timer that is going to trigger the callback inside the setTimeout

Alt Text

and the next statement is pushed into the call stack

Alt Text

Here's the event loop again

Alt Text

The event loop did not find an empty stack so it does nothing again. The execution continues with the next, and final, statement of the foo() function

Alt Text

Lets get back to the web API, which set up a timer for a callback function. Now that the timer has ended, the browser sends the callback message to the message queue

Alt Text

After the last statement got executed, it is removed from the stack, and, as soon as there is nothing else inside the foo() function declaration, the oldest foo() frame is removed from the call stack too!

Now, the event loop may be more lucky

Alt Text

The event loop checks for any messages waiting in the queue

Alt Text

and sends the message's associated function to the call stack

Alt Text

Finally, the JS runtime executes the last frame and removes it form the call stack

Alt Text


Posted on by:

kapantzak profile

John Kapantzakis


Web developer - want to learn something new every day


markdown guide

Very nice article! Thank you for your effort!


Great article, but one question howโ€™s this asynchronous ?


Thanks @amineamami !
According to MDN: Asynchronous , asynchronous code may refer to multiple related tasks happening without waiting for each other to complete.

In our case, if the code was not asynchronous, the setTimeout call whould have blocked the execution of the program until it was completed printing "Two" at the console.

But this is not the case. The program continues executing, printing "three" and, after that, the callback of the setTimeout is called, printing "Two" at the end.


Hmm, it seemed to me just like synchronous execution with a bit of instructions reordering.

Thats right! Javascript language itself does not have any asynchrony built in.
The environment (browser, node etc) is the one that arranges the events resulting in asynchronous execution (the use o callbacks, promises, ajax calls etc)



On your description it shows the Web API putting "two" on the message queue but when the message is extracted from the message queue you are showing that is done by the event loop instead, Is this correct? Does the Web API always push to the message queue while the event loop extracts from the queue, or are you just missing showing the web API managing the both inserting and extracting to the message queue after being triggered by the event loop?


One of the greatest articles to clear all the doubts about event loop.
Thanks man


Awesome! Maybe make it a gif someday?!