DEV Community

Cover image for Asynchronous Operations in JavaScript: The Event Loop
Mosope (Deborah) Oduwole
Mosope (Deborah) Oduwole

Posted on • Edited on • Originally published at deborahtech.hashnode.dev

Asynchronous Operations in JavaScript: The Event Loop

Introduction
JavaScript is Synchronous by Default
Synchronous vs Asynchronous Operations
The Event Loop
How it Works
Importance of the Event Loop
Conclusion


Introduction

Picture this: you just developed a web application that has to fetch data from a server, update the user interface, and respond to all of the user actions in real-time, but you’re worried about whether your code will be able to juggle these tasks efficiently. Well, no need to worry, this is where the event loop comes in.

In this article, I’ll go over how the event loop works, the differences between synchronous and asynchronous operations in JavaScript, and the importance of the event loop as a necessary non-blocking architecture.

Javascript is Synchronous by Default

By default, Javascript is synchronous and code is read sequentially in order from top to bottom. Since JS is single-threaded, each task must wait for the completion of the previous one, before proceeding to the next. What this means is that each line of code is processed, one at a time, and only one operation/function is executed at any given moment.

diagram showing the synchronous nature of javascript

In JavaScript, there is no way to run multiple pieces of code in parallel and any attempt to do parallelism in a language that is synchronous and single-threaded at its core is ambitious. Understanding the synchronous nature of JavaScript will help you realize how web applications respond to user interactions and handle tasks.

function greet(name) {
    return `Hello, ${name}!`;
}

const greeting = greet("Deb");
console.log(greeting);                                                 
Enter fullscreen mode Exit fullscreen mode

In this example, Javascript executes the code in the order it’s written. The ‘greet’ function is called with the argument ‘Deb’. The function then returns a greeting string which is then logged to the console.

Output:

Hello, Deb!
Enter fullscreen mode Exit fullscreen mode

Each line waits for the previous line to finish before executing. Therefore, the function must be completed before the result can be assigned to ‘greeting’.

Synchronous vs Asynchronous Operations

sync vs async image diagram

Before getting into what the event loop is, I’ll touch a little bit on what asynchronous operations are and the differences between synchronous and asynchronous operations in JavaScript. Asynchronous operations are the activities that run independently of a program flow.

As stated earlier, Javascript is synchronous by default and synchronous code creates a blocking behavior where each task/function must finish before the next one starts.

On the other hand, asynchronous operations do not block the execution of subsequent operations and allows javascript to attend to other tasks while waiting for the completion of that particular asynchronous task. Simply put, if you declare a function as asynchronous (async), it means the function has code that will require time to complete, and such a function will be deferred while the synchronous code runs first.

Since there’s no blocking, the next synchronous code can be executed without finishing the previous async one and any async code that is ready to execute will be queued in the event queue.

// Synchronous code
console.log("Step 1");
console.log("Step 2");
Enter fullscreen mode Exit fullscreen mode

Remember synchronous code is executed line-by-line. Here, JavaScript executes the statements in the order they are written.

Output:

Step 1
Step 2
Enter fullscreen mode Exit fullscreen mode

On the other hand, asynchronous code allows JavaScript to continue executing while waiting for an operation to complete.

// Asynchronous code
console.log("1st Function");

setTimeout{function(){ // WEB API
  console.log("2nd Function");
},2000);

console.log("3rd Function");
Enter fullscreen mode Exit fullscreen mode

Output:

1st Function
3rd Function
2nd Function
Enter fullscreen mode Exit fullscreen mode

since the first and third functions are synchronous, they get executed first while the second function gets removed from the call stack and is handled by the web API. The web API asynchronously orders it to wait for 2000ms before being put into the event queue, which will thereafter be placed back into the empty call stack by the event loop and finally executed.

The Event Loop

In its simplest definition, the event loop is a way of synchronously processing asynchronous events.

In a more elaborate definition, the event loop is a continually running code loop in the Javascript runtime that allows for asynchronous operations to be executed when needed. This means it allows for JavaScript’s limiting design to handle many tasks efficiently.

It spins and stays in your code background until it has specific JavaScript tasks to run. For example, clicking a button that has code associated with it from a click event handler, or when you load an external file, in cases like these, the event loop remains in the insides of the javascript runtime to execute any javascript code when needed.

What all this means is that although JavaScript is single-threaded, the event loop enables JavaScript to appear to be able to run things asynchronously by offloading things to APIs and processing those events coming in when it can.

Before I explain how the event loop works, there are a few specific concepts within the JavaScript runtime you need to understand:

  • Call Stack: A call stack keeps track of what functions are called and in what order to execute them. It executes synchronous code in sequential order.

  • Web APIs: These are the tools that handle asynchronous tasks.

  • Callback: This is a function that is passed into another function as an argument. It helps execute code in response to an event.

  • Event/Callback Queue: This holds tasks waiting to be executed once the call stack is clear.

How it Works

The call stack runs synchronous code until it’s empty. When an asynchronous code is added to the call stack, it gets transferred to the API which then processes the task before it gets sent to the event queue.

The event loop process

Callbacks/functions that have been completed by the API get added to the event queue and the event loop is constantly looking within the event queue to see if there is any new event/task that javascript needs to act on.

Note that JavaScript can’t act on the events until the call stack is empty. Therefore, once the call stack is empty, the event loop will grab the event from the queue and place that into the call stack to be executed like other regular functions.

Importance of the Event Loop

  • It keeps your code responsive while performing tasks in the background.

  • It helps manage your tasks effectively by monitoring the call stacks and the callback queue.

  • It provides a workaround for JavaScript to perform non-blocking operations where multiple tasks can be handled concurrently.

  • It prevents your program from going into callback hell. Callback hell happens when multiple callbacks are nested within each other making the code difficult to read or maintain.

Conclusion

The behavior of the event loop determines when code in your application is run. The more knowledge you have surrounding the use and need for the event loop, the more you can understand why your code runs when it does.

Happy coding besties!

Top comments (0)