DEV Community

aarthirs
aarthirs

Posted on

# JavaScript Async Explained Like a Grocery Store 🛒

When I first learned JavaScript's Event Loop, I kept reading explanations like:

"Asynchronous tasks are offloaded to Web APIs and their callbacks are placed into the Microtask Queue or Macrotask Queue."

I memorized the words.

But I didn't actually understand what was happening.

Then I started thinking about JavaScript like a grocery store.

JavaScript = One Cashier

Imagine a store with only one cashier.

The cashier can only serve one customer at a time.

That's JavaScript.


`console.log("A");
console.log("B");
console.log("C");`
Enter fullscreen mode Exit fullscreen mode

Output:

A
B
C
Enter fullscreen mode Exit fullscreen mode

Simple. One task after another.


The Problem

Now imagine a customer says:

"Wait 5 seconds before helping the next customer."

If the cashier literally waited 5 seconds, the entire store would stop moving.

That's exactly what would happen if JavaScript handled timers itself.


Browser Web APIs = Helpers

Instead, JavaScript asks a helper:

`setTimeout(() => {
  console.log("Hello");
}, 5000);`
Enter fullscreen mode Exit fullscreen mode

JavaScript says:

"Hey Browser, can you watch this timer for me?"

The browser helper takes the job.

JavaScript immediately continues working.

Start
End
Enter fullscreen mode Exit fullscreen mode

After 5 seconds, the helper comes back and says:

"The timer finished."


Callback Queue = Waiting Line

The browser cannot interrupt JavaScript directly.

So it places the callback into a waiting line.

Browser Helper
      ↓
Callback Queue
Enter fullscreen mode Exit fullscreen mode

The callback waits until JavaScript is free.


Event Loop = Store Manager

The Event Loop is like a manager constantly checking:

Is the cashier busy?
Enter fullscreen mode Exit fullscreen mode

If yes:

Wait
Enter fullscreen mode Exit fullscreen mode

If no:

Take the next customer from the waiting line
Enter fullscreen mode Exit fullscreen mode

That's all the Event Loop does.


Why Does Promise Run Before setTimeout?

`console.log("Start");

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

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

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

Output:

Start
End
Promise
Timeout
Enter fullscreen mode Exit fullscreen mode

Because JavaScript has two waiting lines:

High Priority Line

  • Promise.then()
  • queueMicrotask()

Normal Line

  • setTimeout()
  • setInterval()
  • DOM events

The Event Loop always clears the high-priority line first.

That's why Promise executes before setTimeout.


What About fetch()?

`fetch("/users")
  .then(res => res.json())
  .then(data => console.log(data));`
Enter fullscreen mode Exit fullscreen mode

The browser handles the network request.

JavaScript doesn't sit around waiting for the server.

Once the response arrives, the callback gets added to the queue and runs when JavaScript is ready.


Why Do Web Workers Exist?

Imagine the cashier receives a task that takes 10 minutes.

Nobody else gets served.

The store freezes.

That's what happens when JavaScript performs heavy calculations on the main thread.

Web Workers solve this by hiring another cashier.

Heavy work runs on a separate thread while the main UI remains responsive.


Final Mental Model

Whenever you see async JavaScript:

JavaScript = Cashier

Browser Web APIs = Helpers

Callback Queue = Waiting Line

Event Loop = Manager

Web Workers = Extra Cashiers
Enter fullscreen mode Exit fullscreen mode

Once this model clicks, the Event Loop becomes much easier to understand than memorizing definitions.

Top comments (1)

Collapse
 
aarthirs profile image
aarthirs

Did you find this post useful? Follow me for more developer-friendly content, share your thoughts in the comments, and help others discover it by sharing this post.