DEV Community

Cover image for Understanding the JavaScript Event Loop in 5 Minutes 🕒✨
Burhanuddin S. Tinwala
Burhanuddin S. Tinwala

Posted on

1

Understanding the JavaScript Event Loop in 5 Minutes 🕒✨

JavaScript’s Event Loop is the secret sauce behind its non-blocking, asynchronous nature. 🤔 Sounds tricky? No worries! By the end of this 5-minute guide, you’ll not only understand it but also see it in action with fun code examples! 🚀

Let’s decode the magic together. 🧙‍♂️✨


What Is the Event Loop? 🌀

The Event Loop is JavaScript’s mechanism for handling asynchronous operations while ensuring the main thread isn’t blocked. 🛠️

Here’s the crew working behind the scenes:

  • Call Stack 🗂️: Where your currently running code lives.
  • Web APIs 🌐: Handle async tasks like timers, HTTP calls, or DOM events.
  • Task Queue 🕒: Stores callbacks waiting to run after the stack is clear.
  • Microtask Queue ⚡: Reserved for tasks like Promises (higher priority than the Task Queue).

Think of it as a busy chef 🧑‍🍳 managing orders (tasks) efficiently with the help of their team (Web APIs).


How the Event Loop Works 🔄

Example 1: Execution Order 🎯

console.log("Start");

setTimeout(() => console.log("Timeout"), 0);

Promise.resolve("Promise Resolved").then(console.log);

console.log("End");
Enter fullscreen mode Exit fullscreen mode

What Happens? 🧩

  1. console.log("Start") executes and logs Start.
  2. setTimeout sends its callback to the Task Queue. 🕒
  3. Promise.resolve sends its .then callback to the Microtask Queue. ⚡
  4. console.log("End") executes and logs End.
  5. The Microtask Queue is processed first → logs Promise Resolved.
  6. The Task Queue is processed → logs Timeout.

Output:

Start
End
Promise Resolved
Timeout
Enter fullscreen mode Exit fullscreen mode

Example 2: Nested Tasks 🌀

console.log("First");

setTimeout(() => {
  console.log("Second");
  Promise.resolve().then(() => console.log("Third"));
}, 0);

console.log("Fourth");
Enter fullscreen mode Exit fullscreen mode

What Happens? 🧩

  1. Logs First.
  2. setTimeout adds its callback to the Task Queue.
  3. Logs Fourth.
  4. Task Queue processes the setTimeout callback → logs Second.
  5. Inside that callback, a promise resolves → logs Third.

Output:

First
Fourth
Second
Third
Enter fullscreen mode Exit fullscreen mode

Adding Async/Await to the Mix 🔀

When using async/await, the promise-related tasks go straight to the Microtask Queue. ⚡

Example 3: Mixing Timers and Async/Await

async function fetchData() {
  console.log("Fetching data...");
  return "Data fetched!";
}

console.log("Start");

fetchData().then(console.log);

setTimeout(() => console.log("Timeout"), 0);

Promise.resolve("Immediate Promise").then(console.log);

console.log("End");
Enter fullscreen mode Exit fullscreen mode

What Happens? 🧩

  1. Logs Start.
  2. Calls fetchData → logs Fetching data....
  3. setTimeout adds its callback to the Task Queue.
  4. Promise.resolve adds its .then callback to the Microtask Queue.
  5. Logs End.
  6. Microtasks first:
    • Logs Immediate Promise.
    • Resolves the fetchData promise → logs Data fetched!.
  7. Finally, Task Queue:
    • Logs Timeout.

Output:

Start
Fetching data...
End
Immediate Promise
Data fetched!
Timeout
Enter fullscreen mode Exit fullscreen mode

Real-Life Analogy 🍔

Imagine a burger joint:

  1. Call Stack: The chef 🧑‍🍳 cooks one dish at a time.
  2. Web APIs: Waitstaff 🛎️ handle orders and prep.
  3. Microtask Queue: Urgent orders (e.g., fix an undercooked patty) are prioritized. ⚡
  4. Task Queue: Regular orders wait in line. 🕒

Thanks to the Event Loop (chef’s system), all tasks are served without chaos! 🎉


Pitfalls and Best Practices ⚠️💡

  1. Avoid Blocking the Event Loop 🚫 Long tasks can freeze your app:

    while (true) {
        // This freezes the browser!
    }
    

    Solution: Offload heavy tasks to Web Workers. 🏗️

  2. Timers Are Not Precise ⏱️

    setTimeout(() => console.log("May not run exactly after 1 second"), 1000);
    
  3. Understand Microtask Priority

    setTimeout(() => console.log("Task Queue"), 0);
    Promise.resolve().then(() => console.log("Microtask Queue"));
    
    // Output:
    // Microtask Queue
    // Task Queue
    
  4. Use Async/Await Wisely 🛠️

    async function process() {
        const result = await fetch("https://api.example.com");
        console.log(await result.json());
    }
    process();
    

Key Takeaways 🏁

  • Microtask Queue tasks run before the Task Queue.
  • Avoid blocking the main thread with heavy computations.
  • Master async/await for clean, efficient asynchronous code.

By understanding the Event Loop, you’ll unlock a superpower in JavaScript development. 🌟 Have questions or examples of your own? Let’s chat in the comments! 💬

Let's connect LinkedIn

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more