Event Loop Architecture
The event loop is the mechanism that allows JavaScript to perform non-blocking operations despite being single-threaded. It continuously monitors the call stack and callback queues.
Components
- Call Stack: Where synchronous code executes
- Web APIs: Browser-provided APIs (setTimeout, fetch, DOM events)
- Callback Queue (Macrotask Queue): Where completed async callbacks wait
- Microtask Queue: Where Promise callbacks wait (higher priority)
How It Works
┌───────────────────────┐
│ Call Stack │
│ (synchronous code) │
└──────────┬────────────┘
│
▼
┌───────────────────────┐
│ Event Loop │
│ (checks if stack │
│ is empty) │
└──────────┬────────────┘
│
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ Micro │ │ Macro │
│ Task │ │ Task │
│ Queue │ │ Queue │
└─────────┘ └─────────┘
console.log('1'); // Synchronous
setTimeout(() => {
console.log('2'); // Macrotask
}, 0);
Promise.resolve().then(() => {
console.log('3'); // Microtask
});
console.log('4'); // Synchronous
// Output: 1, 4, 3, 2
Call Stack and Web APIs
When JavaScript encounters an async operation, it delegates to the browser's Web APIs and continues executing the next line.
console.log('Start');
// setTimeout is a Web API
setTimeout(() => {
console.log('Timeout callback');
}, 2000);
// fetch is a Web API
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data));
console.log('End');
Execution flow:
console.log('Start')→ executes immediatelysetTimeout→ browser starts a 2-second timer, continuesfetch→ browser starts network request, continuesconsole.log('End')→ executes immediately- After 2 seconds, timeout callback moves to macrotask queue
- When fetch completes,
.thencallback moves to microtask queue - Event loop processes queues when call stack is empty
Web API Examples
setTimeout/setIntervalfetch/XMLHttpRequest- DOM event listeners
requestAnimationFrameIndexedDBWeb Workers
Callback Queue
The callback queue (also called the task queue or macrotask queue) holds callbacks from completed async operations. The event loop pushes them to the call stack when it's empty.
// Multiple async operations
console.log('A');
setTimeout(() => {
console.log('B'); // Macrotask 1
}, 0);
setTimeout(() => {
console.log('C'); // Macrotask 2
}, 0);
setTimeout(() => {
console.log('D'); // Macrotask 3
}, 0);
console.log('E');
// Output: A, E, B, C, D
Key Rules:
- The event loop checks if the call stack is empty
- If empty, it first drains all microtasks (Promises)
- Then it takes one macrotask from the queue
- Process repeats
Event Loop Cycle
// The event loop essentially does this:
while (queueIsNotEmpty) {
// Wait for call stack to be empty
while (callStackIsNotEmpty) {
// do nothing
}
// First, process all microtasks
while (microtaskQueueIsNotEmpty) {
dequeueMicrotask();
}
// Then, process one macrotask
dequeueMacrotask();
}
This is why microtasks (Promises) always run before macrotasks (setTimeout), even with 0 delay.
Practice Problems
Create a reusable React component implementing Event Loop. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Event Loop using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Event Loop for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What is the primary purpose of the event loop?
2. What is the output of this code? ```javascript console.log('1'); setTimeout(() => console.log('2'), 0); console.log('3'); ```
3. Which queue does Promise.then() callback go to?
4. What happens first when the event loop runs?
Flashcards
Question
What is the event loop?
Click to reveal answer
Answer
A mechanism that continuously monitors the call stack and callback queues, pushing callbacks to the stack when it's empty.
Question
What are Web APIs?
Click to reveal answer
Answer
Browser-provided APIs (setTimeout, fetch, DOM events) that handle async operations outside the JavaScript engine.
Question
What is the difference between macrotask and microtask queues?
Click to reveal answer
Answer
Microtasks (Promises) have higher priority and are all processed before the next macrotask (setTimeout) is taken.
Question
Why does setTimeout(fn, 0) not execute immediately?
Click to reveal answer
Answer
The callback goes to the macrotask queue. It only runs after the call stack is empty and all microtasks are processed.
Question
What is Event Loop?
Click to reveal answer
Answer
Event Loop is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.JavaScript is single-threaded but non-blocking thanks to the event loop
- 2.Web APIs handle async operations outside the JS engine
- 3.Microtasks (Promises) always run before macrotasks (setTimeout)
- 4.The event loop continuously checks if the call stack is empty
- 5.Understanding the event loop is crucial for debugging async code
Interview Tips
- •Trace through async code step by step to predict output order
- •Explain why Promise.then runs before setTimeout even with 0 delay
- •Discuss the event loop in the context of UI responsiveness
- •Compare event loop behavior in browsers vs Node.js
Cheat Sheet
Event Loop Cheat Sheet
Components
- Call Stack: Executes synchronous code
- Web APIs: Handle async operations (setTimeout, fetch)
- Microtask Queue: Promise callbacks (high priority)
- Macrotask Queue: setTimeout, setInterval callbacks
Event Loop Cycle
- Check if call stack is empty
- If empty, drain ALL microtasks
- Process ONE macrotask
- Repeat
Execution Order
- Synchronous code
- Microtasks (Promises)
- Macrotasks (setTimeout)
Key Insight
Even setTimeout(fn, 0) waits for microtasks to complete first.