I wrote this series because JavaScript has many "asynchronous" mechanisms (await, setTimeout, Promise, requestAnimationFrame) that look similar but behave very differently.
At first, I assumed they were interchangeable but that assumption quickly broke when I started debugging:
setTimeout(..., 0) doesn’t "run immediately"await pauses a function but doesn’t freeze the pageThese behaviours only make sense with the right mental model. This series builds that model by experimenting with small code snippets.
The core idea is simple:
JavaScript runs to completion inside a task, and nothing interrupts it.
From there, we layer in:
async/await (pausing a function without pausing JavaScript), requestAnimationFrame (the missing pre-render scheduling layer), and finally, This series is for you if you’ve ever felt that JavaScript async behavior is:
You don’t need prior knowledge of the event loop. The goal is to build a mental model you can use to reason about behavior — not just memorize it.
Each article builds on the previous one. You can jump around, but the payoff is highest if you go in order.
You can also read this series on my website (recommended for the best reading experience).
Here’s how the model unfolds:
1) The JavaScript Runtime: Fixing the Mental Model
Why doesn’t setTimeout interrupt your code? This article breaks the illusion: JavaScript runs synchronously, and async APIs don’t interrupt. Instead, they schedule.
Read it here.
2) Macrotasks: What a Task Actually Is
If nothing can interrupt JavaScript, when does anything else run? This article reframes tasks as entry points into execution, not chunks of work.
Read it here
3) Microtasks: Why Promises Run First
Why do Promises always run before setTimeout? This article reveals microtasks as mandatory continuations that must run before JavaScript moves on.
Read it here
4) async / await: Pausing Functions Without Pausing the World
Does await pause your program or just your function? This article shows how await actually works.
Read it here.
5) Rendering Is a Browser Decision, Not a JavaScript One
You updated the DOM. So why didn’t the screen change? This article explains why rendering is not triggered by JavaScript, but gated by it.
Read it here.
6) requestAnimationFrame: The Missing Scheduling Layer
If rendering only happens at certain moments, how do you run code at the right time? This article introduces requestAnimationFrame as the missing scheduling layer.
Read it here.
7) The Scheduling Boundaries Behind Responsive UI
Why do UIs freeze, skip updates, or feel laggy? This article connects the event loop to real-world UI behavior and shows how to work with the browser, not against it.
Read it here
This is the model everything in this series builds toward:
requestAnimationFrame callbacks
requestAnimationFrame)
This series was originally written and is maintained on my website. If you prefer a single place with all updates and future articles, you can follow along there.
If you want to discuss edge cases, counterexamples, or how this interacts with real applications, I’m always happy to chat.
My personal website is https://marshateo.com.