DEV Community

gunjangidwani
gunjangidwani

Posted on

Event Loop & Asynchronous JS

JavaScript is single-threaded, meaning it executes code in a single sequence. But thanks to the Event Loop and asynchronous features like setTimeout, Promises, and async/await, it can handle tasks like I/O operations, timers, and HTTP requests without blocking execution.

🔁 Event Loop: The Core Concept
The event loop allows JavaScript to perform non-blocking operations by putting them in a queue and continuing to execute other code. When the call stack is clear, it checks the queue and processes the next task.

🧠 Components Involved:
Call Stack
Where JS code is executed. It's LIFO (Last In, First Out).

  • Web APIs (provided by browser)
    Handles timers, DOM events, fetch requests, etc.

  • Callback Queue (Task Queue)
    Stores callback functions to be executed after the stack is empty.

  • Microtask Queue
    For promises and queueMicrotask. Has higher priority than the callback queue.

🔄 How It Works (Simplified Flow)

console.log("Start");

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

Promise.resolve().then(() => {
  console.log("Promise");
});

console.log("End");

Start
End
Promise
Timeout

Enter fullscreen mode Exit fullscreen mode

✅ Why?
console.log("Start") → Synchronous → executed immediately.

setTimeout(...) → Sent to Web APIs → callback sent to task queue after delay.

Promise.then(...) → Microtask queue.

console.log("End") → Synchronous → executed.

Microtask queue runs: Promise.

Task queue runs: Timeout.

📘 Asynchronous JS Tools

  1. setTimeout / setInterval – Schedule tasks.
  2. Promises – Represent a future value.
  3. async/await – Syntactic sugar for working with promises.

Example with async/await:

async function fetchData() {
  console.log("Fetching...");
  const response = await fetch("https://api.example.com");
  const data = await response.json();
  console.log("Done:", data);
}

fetchData();
console.log("This runs first");

Enter fullscreen mode Exit fullscreen mode

📌 Summary

  1. JavaScript is non-blocking via the event loop.
  2. Async operations are deferred via Web APIs and queued via task and microtask queues.
  3. Promises and async/await make async code more readable and manageable.
  4. Microtasks (Promises) always run before tasks (setTimeout, etc.).

Top comments (4)

Collapse
 
nevodavid profile image
Nevo David

Pretty cool walk through on async stuff - still trips me up sometimes but this clears things up a bit for me.

Collapse
 
bhuvi_d profile image
Bhuvi D

Nice, thanks for sharing !

Collapse
 
dotallio profile image
Dotallio

Love how you clarified the microtask vs task queue flow - I've seen so many get tripped up by promise timing! Ever run into surprising behavior when chaining multiple async operations together?

Collapse
 
gunjangidwani profile image
gunjangidwani

Thanks! I appreciate that. I actually have encountered some surprising behavior when chaining multiple async operations. For example, I once had a situation where I was chaining several Promises together, and I didn't account for the fact that each Promise in the chain is only resolved once the previous one is fully resolved. This led to some unexpected delays and race conditions in my code. It was a good learning experience and highlighted the importance of understanding the timing and resolution order of Promises when chaining them. Have you run into anything similar?

Some comments may only be visible to logged-in visitors. Sign in to view all comments.