SKIP TO MAIN
-- views

Understanding event loop in JavaScript

February 20, 2024

Javascript is a single-threaded, non-blocking, and asynchronous programming language that can run natively in a browser.

Single-Threaded#

means the language can execute only one instruction at a time. this distinguishes it from multi-threaded programming languages that execute multiple instructions at once.

Single-Threaded and Multi-Threaded

Non-Blocking and Asynchronous#

mean the language does not block the execution of the next operation. In other words, the program does not wait for a specific previous operation to finish executing before it moves to the next one.

It leverages mechanisms like callbacks, promises, and async/await to manage asynchronous tasks.

The event loop plays a role in overseeing the execution flow, ensuring that the single-threaded JavaScript can efficiently handle multiple tasks concurrently

Event Loop#

The event loop is responsible for pulling stuff out of the queue and placing it onto the call stack (function execution stack) making sure that instructions don't block the execution of other code

Web APIs#

Web APIs are built within the web browser providing JavaScript the ability to Manipulate documents, fetch data from the server and more.

Callback Queue#

Callback queue is a data structure where elements are stored in the FIFO (First In First Out) principle means the first element inserted would be the first element to be accessed

Call Stack#

A Call Stack is a mechanism for a JavaScript interpreter to keep track of function calls in a program (what function is currently being run and what functions are called from within that function)

How event loop works

whenever a function gets invoked it gets added to Call Stack, since it's called a stack that means first in, last out. the function gets popped off the stack when it returns a value

let's try to figure out what gets logged to the console:

console.log('First log');
 
// setTimeout delays a task without blocking the main thread
setTimeout(() => {
    console.log('Last log');
}, 100);
 
console.log('Second log');

let's take a look at the execution order of the previous code:

  1. We invoked console.log('First log') which will get added directly to the call stack
  2. The callback we passed to setTimeout gets added to the Web APIs
  3. The timer runs, in the meanwhile the other console.log will be added to the call stack
Normal tasks
  1. First log and Second log get logged and once the timer finishes running it moves the callback to the macrotask queue then event loop will add that callback to the call stack once it gets empty.
Web APIs task

You may notice that callback queues consist of two queues microtask & macrotask

The event loop always gives higher priority to the microtask queue

Let's take this example, what do you think the order of the logs is?

console.log('First');
 
setTimeout(() => {
    console.log('Second');
}, 100);
 
Promise.resolve('Third').then(console.log);
 
console.log('Fourth');

Following the previous concepts:

  1. console.log('First') and console.log('Fourth') get added to the call stack, which logs First and Fourth
  2. Both Promise and setTimeout will be already added to the task queue and since the microtask queue has higher priority over the macrotask, Third gets logged
  3. Finally, the setTimeout callback gets invoked, which therefore logs Second

References#

GET IN TOUCH

Let’s work together

I build exceptional and accessible digital experiences for the web

WRITE AN EMAIL