techStackGuru

JavaScript Event Loop


In JavaScript, an event loop is a crucial aspect of handling asynchronous operations. It manages the execution of code in an event-driven environment and is an integral part of JavaScript's concurrency model.

event-loop-1

How the event loop works

  • Event Queue: Event queues (also known as callback queues or task queues) are used to queue up asynchronous tasks like DOM events, network requests, and timer callbacks.
  • Call Stack: As JavaScript is single-threaded, it can only execute one piece of code at a time. Data structures such as the call stack keep track of the execution of synchronous code. In call stacks, functions are pushed onto them when they are called, and they are removed when they are finished.
  • Event Loop: In the event loop, two main sources are constantly checked: the call stack and the event queue. Event loops push tasks to call stacks if there are tasks in the event queue and the call stack is empty.
  • Non-blocking: An asynchronous operation does not prevent subsequent code from being executed. Rather than running in the background, they are completed in the background, and their respective callbacks are added to the event queue after they are complete.
  • Key of Event Loop

  • Event Loops manage two crucial data structures: call stacks and event queues.
  • The call stack executes synchronous code according to the Last-In-First-Out (LIFO) principle.
  • The event queue holds callbacks for asynchronous operations triggered by functions such as setTimeout.
  • JavaScript is non-blocking since the Event Loop processes event queue items only when the call stack is empty.
  • Example

    console.log("Start Script"); //1
    
    setTimeout(() => {
      console.log("This message will be delayed by 2 seconds"); //4
    }, 2000);
    
    console.log("This message will be printed immediately"); //2
    
    for (let i = 0; i < 1000000; i++) {
      // Simulate a long-running task
    }
    
    console.log("This message will be printed after the loop"); //3
    
    // Output
    Start Script
    This message will be printed immediately
    This message will be printed after the loop
    This message will be delayed by 2 seconds
  • Start Script: As part of the main script execution, this message gets printed immediately.
  • setTimeout(): It schedules a callback function for execution after two seconds. Rather than being placed on the call stack, the callback is placed in the event queue.
  • This message will be printed immediately(): Because it is the next line in the main script, it executes next.
  • Long-running loop:A million iterations are performed on this loop to simulate a blocking task. Due to JavaScript's single-threaded nature, other events, such as the setTimeout callback, must wait until the next thread.
  • Event Loop: During loop execution, the Event Loop checks if the call stack is empty. Despite the setTimeout timer elapsed, the callback cannot execute yet since the loop is blocking the stack.
  • This message will be printed after the loop:As soon as the loop is completed, the call stack is empty again. The setTimeout callback is then moved from the queue to the stack and executed by the Event Loop.
  • Example 2

    function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
        resolve("Data retrieved successfully!");
        }, 2000);
    });
    }
    
    console.log("1");
    
    fetchData().then((data) => {
    console.log("4:", data);
    });
    
    console.log("2");
    
    for (let i = 0; i < 1000000; i++) {
    // Simulate a long-running task
    }
    
    console.log("3");
    
    // Output
    1
    2
    3
    4: Data retrieved successfully!