Explain how the JavaScript event loop works. What's the difference between microtasks and macrotasks?
3 minintermediatejavascripteventloopworks
Quick Answer
The JavaScript event loop is the mechanism that allows JavaScript to handle asynchronous operations despite being single-threaded.
Detailed Answer
Explain how the JavaScript event loop works. What's the difference between microtasks and macrotasks?
Answer: The JavaScript event loop is the mechanism that allows JavaScript to handle asynchronous operations despite being single-threaded. Here's how it works:
Components:
- Call Stack: Executes synchronous code (LIFO - Last In, First Out)
- Web APIs: Browser APIs for timers, DOM events, HTTP requests
- Task Queue (Macrotask Queue): For callbacks from setTimeout, setInterval, DOM events
- Microtask Queue: For callbacks from Promises, queueMicrotask, MutationObserver
Execution Flow:
- Execute all synchronous code in the call stack
- When call stack is empty, process ALL microtasks first
- Then process ONE macrotask
- Repeat
Microtasks vs Macrotasks:
- Microtasks (higher priority): Promise callbacks (.then, .catch, .finally), queueMicrotask(), MutationObserver callbacks
- Macrotasks (lower priority): setTimeout/setInterval callbacks, DOM event callbacks, I/O operations
Example:
console.log('1'); // Synchronous
setTimeout(() => console.log('2'), 0); // Macrotask
Promise.resolve().then(() => console.log('3')); // Microtask
console.log('4'); // Synchronous
// Output: 1, 4, 3, 2
Follow-up: How would you handle a situation where you need to execute multiple async operations in parallel but want to wait for all of them to complete?
Answer:
Use Promise.all() for parallel execution with all-or-nothing behavior, or Promise.allSettled() for handling individual failures:
// All-or-nothing approach
async function fetchMultipleData() {
try {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()),
fetch('/api/comments').then(res => res.json())
]);
return { users, posts, comments };
} catch (error) {
console.error('One or more requests failed:', error);
throw error;
}
}
// Handle individual failures
async function fetchWithFallback() {
const results = await Promise.allSettled([
fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()),
fetch('/api/comments').then(res => res.json())
]);
return results.map((result, index) => {
if (result.status === 'fulfilled') {
return result.value;
} else {
console.error(`Request ${index} failed:`, result.reason);
return null; // or default value
}
});
}