JavaScript Runtime
Understanding JavaScript's single-threaded execution model and how the event loop processes asynchronous tasks.
Event Loop
How the Event Loop Works
Understanding JavaScript's single-threaded execution model
// The Event Loop processes tasks in this order:
// 1. Call Stack (synchronous code)
// 2. Microtask Queue (Promises, queueMicrotask)
// 3. Task Queue (setTimeout, setInterval, I/O)
console.log('1'); // Synchronous - goes to call stack
setTimeout(() => {
console.log('2'); // Task - goes to task queue
}, 0);
Promise.resolve().then(() => {
console.log('3'); // Microtask - goes to microtask queue
});
console.log('4'); // Synchronous - goes to call stack
// Output: 1, 4, 3, 2
// Why? Event loop processes microtasks before tasksEvent Loop Visualization
Interactive diagram showing how the event loop works
Event Loop Visualization
Call Stack
Synchronous code executes here
console.log()
function calls
variable assignments
Event Loop
Moves tasks from queues to call stack
Checks if call stack is empty
Processes all microtasks first
Then process tasks in the task queue
Microtask Queue
Promises, queueMicrotask, process.nextTick
Promise.then()
queueMicrotask()
async/await
Task Queue
setTimeout, setInterval, I/O operations
setTimeout()
setInterval()
fetch()
Call Stack
→
Event Loop
→
Microtask
→
Task
Interactive Example
Step: 0 / 12
Ready to start
Code
1console.log('Start');
2setTimeout(
() => console.log(
'Timeout called'), 0);
3Promise.resolve().then(
() => console.log(
'Promise resolved'));
4console.log('End');
Event Loop Flow
Call Stack
↓
Process
Microtask Queue
↓
Process
Task Queue
↻
Event Loop
Console Output
Key Concepts
Microtasks (High Priority)
- • Processed before next render
- • Include Promise callbacks
- • queueMicrotask() function
- • process.nextTick() (Node.js)
Tasks (Lower Priority)
- • Processed after current execution
- • Include setTimeout, setInterval
- • I/O operations, fetch requests
- • DOM event handlers
Microtasks vs Tasks
Different types of asynchronous tasks and their priorities
// Microtasks (processed before next render)
Promise.resolve().then(() => console.log('Microtask 1'));
queueMicrotask(() => console.log('Microtask 2'));
// Tasks (processed after current execution and microtasks)
setTimeout(() => console.log('Task 1'), 0);
setInterval(() => console.log('Task 2'), 1000);
// Event listeners are also tasks
button.addEventListener('click', () => {
console.log('Click event (task)');
});
// Process.nextTick (Node.js only - highest priority microtask)
process.nextTick(() => console.log('Next tick'));Event Loop Example
Practical example showing event loop execution order
function eventLoopExample() {
console.log('Start');
setTimeout(() => {
console.log('Timeout 1');
Promise.resolve().then(() => {
console.log('Promise in timeout');
});
}, 0);
Promise.resolve().then(() => {
console.log('Promise 1');
setTimeout(() => {
console.log('Timeout in promise');
}, 0);
});
console.log('End');
}
// Output:
// Start
// End
// Promise 1
// Timeout 1
// Promise in timeout
// Timeout in promise