Event Loop
This lesson explains Event Loop in JavaScript with beginner-friendly examples, practical use cases, and clear best practices.
JavaScript Event Loop Overview
The JavaScript event loop is the mechanism that allows JavaScript to handle
asynchronous tasks while staying single-threaded. It coordinates the call
stack, Web APIs, callback queue, microtask queue, and rendering process so
JavaScript can run timers, promises, events, and API callbacks without
blocking the browser.
Understanding the event loop is essential for mastering asynchronous
JavaScript, promises, async/await, timers, event handlers, UI updates,
performance optimization, and interview questions about execution order.
| Event Loop Concept | Description | Common Usage |
| Call Stack | Runs synchronous JavaScript code. | Function execution. |
| Web APIs | Browser-provided async features. | Timers, fetch, DOM events. |
| Callback Queue | Stores timer and event callbacks. | setTimeout and event handlers. |
| Microtask Queue | Stores promise callbacks. | then, catch, finally, queueMicrotask. |
| Event Loop | Moves queued tasks to the call stack when it is empty. | Async execution control. |
| Rendering | Browser updates the UI between event loop cycles. | Layout, paint, animations. |
JavaScript Event Loop Example
console.log("Start");
setTimeout(function() {
console.log("Timer");
}, 0);
Promise.resolve().then(function() {
console.log("Promise");
});
console.log("End");
The output is Start, End,
Promise, and then Timer. Synchronous code runs
first, promise microtasks run next, and timer callbacks run after that.
Top 10 JavaScript Event Loop Examples
The following examples show common event loop patterns used in asynchronous
JavaScript, promises, timers, async/await, DOM events, and interview
questions.
| # | Example | Syntax |
| 1 | Synchronous Code | console.log("Start"); console.log("End"); |
| 2 | setTimeout Callback | setTimeout(function() { console.log("Timer"); }, 0); |
| 3 | Promise Microtask | Promise.resolve().then(function() { console.log("Promise"); }); |
| 4 | queueMicrotask | queueMicrotask(function() { console.log("Microtask"); }); |
| 5 | Async Await | async function run() { await Promise.resolve(); console.log("Done"); } |
| 6 | Fetch Callback | fetch("/api/users").then(function(res) { return res.json(); }); |
| 7 | DOM Event Task | button.addEventListener("click", function() { console.log("Clicked"); }); |
| 8 | setInterval Task | setInterval(function() { console.log("Tick"); }, 1000); |
| 9 | Nested Timer | setTimeout(function() { setTimeout(function() { console.log("Nested"); }, 0); }, 0); |
| 10 | Promise Before Timer | Promise.resolve().then(cb); setTimeout(cb, 0); |
Popular Real-World JavaScript Event Loop Examples
These examples show where event loop behavior matters in real web
applications, especially when working with UI updates, timers, promises,
API calls, and performance-sensitive code.
| Scenario | Event Loop Pattern |
| Show Loading Before API Call | loading.textContent = "Loading"; fetchData().then(renderData); |
| Run Code After Current Stack | setTimeout(function() { console.log("Later"); }, 0); |
| Promise Runs Before Timer | Promise.resolve().then(runTask); setTimeout(runTask, 0); |
| Wait for DOM Update | requestAnimationFrame(function() { updateUI(); }); |
| Debounced Search | setTimeout(function() { search(query); }, 300); |
| Auto Refresh Dashboard | setInterval(function() { refreshData(); }, 60000); |
| Async API Rendering | fetchUsers().then(function(users) { render(users); }); |
| Microtask State Update | Promise.resolve().then(function() { updateState(); }); |
| Avoid Blocking UI | setTimeout(function() { processChunk(); }, 0); |
| Animation Frame | requestAnimationFrame(function() { animate(); }); |
Best Practices
- Keep synchronous JavaScript work small to avoid blocking the UI.
- Use promises and
async/await for readable asynchronous workflows. - Remember that promise callbacks run before timer callbacks.
- Use
requestAnimationFrame() for visual updates and animations. - Use debouncing or throttling for frequent events such as input, scroll, and resize.
- Break large tasks into smaller chunks when processing heavy data.
- Avoid creating endless microtask loops that block rendering.
- Use browser developer tools to inspect long tasks and performance issues.
Common Mistakes
- Assuming
setTimeout(..., 0) runs immediately. - Forgetting that promise microtasks run before timer callbacks.
- Blocking the call stack with heavy synchronous loops.
- Expecting UI rendering to happen while JavaScript is still running.
- Creating too many microtasks and delaying rendering.
- Using timers for animations instead of
requestAnimationFrame(). - Ignoring performance problems caused by long-running JavaScript tasks.
Key Takeaways
- The event loop coordinates synchronous and asynchronous JavaScript execution.
- The call stack runs synchronous code first.
- Promise callbacks run in the microtask queue.
- Timer and event callbacks run in the callback queue.
- Microtasks run before normal callback queue tasks.
- Understanding the event loop helps explain async behavior and execution order.
Pro Tip
For JavaScript event loop interview questions, remember this order:
synchronous code first, promise microtasks second, timer and event callbacks
third. This rule explains many common async output questions.