JavaScriptMarch 22, 2026
JavaScript Event Loop Explained
A deep dive into the JavaScript event loop and how it manages async code.
Understanding the event loop is crucial for writing efficient JavaScript. Let’s break it down.
The Call Stack
JavaScript is single-threaded, with one call stack:
javascript
function third() { console.log('Third') }
function second() { third(); console.log('Second') }
function first() { second(); console.log('First') }
first()
// Third, Second, First
Web APIs and Task Queue
javascript
console.log('Start')
setTimeout(() => {
console.log('Timeout')
}, 0)
console.log('End')
// Output: Start, End, Timeout
Microtasks vs Macrotasks
javascript
console.log('1')
setTimeout(() => console.log('2'), 0)
Promise.resolve().then(() => console.log('3'))
console.log('4')
// Output: 1, 4, 3, 2
Microtasks (higher priority):
- Promise callbacks
- queueMicrotask()
- MutationObserver
Macrotasks:
- setTimeout/setInterval
- I/O operations
- UI rendering
Event Loop Cycle
- Execute all synchronous code
- Execute all microtasks
- Execute one macrotask
- Repeat
Practical Example
javascript
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(() => console.log('setTimeout'), 0)
async1()
new Promise((resolve) => {
console.log('promise1')
resolve()
}).then(() => console.log('promise2'))
console.log('script end')
// Output:
// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout