One Event Loop Cycle

Med

An event loop tick (or iteration) is one complete cycle of the event loop. Understanding exactly what happens in each tick is crucial for predicting the order of asynchronous code execution. One tick consists of: execute one macrotask, then drain all microtasks, then potentially render.

Interactive Visualization

JavaScript is single-threaded - one task at a time
IdleTaskLoop1
Running synchronous code
Call Stack
<script>
Microtasks
(empty)
Task Queue
(empty)
CodeLine 1
1console.log('start');
2
3setTimeout(() => {
4 console.log('task 1');
5}, 0);
6
7setTimeout(() => {
8 console.log('task 2');
9}, 0);
10
11console.log('end');
Output
-
Script starts - this is the first task on the call stack
Key Insight: The event loop runs ONE task per iteration, then checks for more work. JavaScript never runs two things at once!

Key Points

  • 1. Execute one macrotask from task queue (if any)
  • 2. Drain ALL microtasks (execute until microtask queue empty)
  • 3. Render (if needed)
  • 4. Repeat
  • If no macrotask, wait for one

Code Examples

Complete Event Loop Order

console.log("Script start");

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

Promise.resolve()
  .then(() => console.log("Promise 1"))
  .then(() => console.log("Promise 2"));

console.log("Script end");

// Output:
// Script start
// Script end
// Promise 1
// Promise 2
// setTimeout

// Execution:
// 1. Run script (macrotask) → logs start, end
// 2. Drain microtasks → Promise 1, Promise 2
// 3. Next tick → setTimeout

One tick = run macrotask, drain all microtasks, render if needed.

setTimeout 0 is Not Immediate

Promise.resolve().then(() => console.log("Promise"));
setTimeout(() => console.log("setTimeout 0"), 0);

// Promise runs before setTimeout 0

// Why? Even with 0ms delay:
// 1. Promise queues microtask (runs this tick)
// 2. setTimeout queues macrotask (runs next tick)

// Microtasks always before next macrotask!

Even setTimeout(..., 0) waits for the next tick, after all microtasks.

Common Mistakes

  • Thinking setTimeout(fn, 0) runs before Promise.then()
  • Not understanding the one-macrotask-per-tick rule

Interview Tips

  • Describe one complete tick: macrotask → all microtasks → render
  • Know why setTimeout 0 is not immediate
  • Be able to trace code execution order