JavaScript Tutorial · Asynchronous JavaScript · Lesson 31 of 44
JavaScript Callbacks and Timers
setTimeout, setInterval and the event loop.
JavaScript runs one thing at a time
JavaScript has a single main thread. Slow work — timers, network requests, file reads — is handed off, and a callback runs later when the result is ready. The event loop decides what runs next.
setTimeout
setTimeout(fn, ms) runs fn once after at least ms milliseconds. Notice the order of the output:
console.log("1. start");
setTimeout(() => console.log("3. timeout (after 0 ms)"), 0);
console.log("2. end of script");
Output
1. start 2. end of script 3. timeout (after 0 ms)
Even with a 0 ms delay, the callback waits until the current code has finished.
setInterval
setInterval(fn, ms) repeats until you call clearInterval:
let ticks = 0;
const id = setInterval(() => {
ticks++;
console.log("tick", ticks);
if (ticks === 3) {
clearInterval(id);
console.log("stopped");
}
}, 100);
Output
tick 1 tick 2 tick 3 stopped
Callback hell
Nesting callbacks inside callbacks quickly becomes unreadable ("the pyramid of doom"). Promises and async/await, covered next, solve that. Test your understanding with the event loop output puzzle.
Test yourself
When does a setTimeout(fn, 0) callback run?
Immediately, before the next lineAfter the current code finishesNeverExactly 0 ms later, interrupting the code
Show answer
Answer: After the current code finishes
Practice next
- Implement debounce() · coding problem
- Microtasks vs Macrotasks · coding problem