setTimeout and setInterval in JavaScript
Timers in JavaScript
setTimeout and setInterval are Web API functions for executing code after a delay or at regular intervals.
setTimeout
Executes a function once after a specified delay (in milliseconds):
const timerId = setTimeout(() => {
console.log("Runs after 2 seconds");
}, 2000);
// Cancel before it fires
clearTimeout(timerId);setTimeout with 0 delay
console.log("1");
setTimeout(() => console.log("2"), 0);
console.log("3");
// Output: 1, 3, 2Even with 0ms delay, the callback goes to the macrotask queue and runs after the current synchronous code completes.
setInterval
Executes a function repeatedly at every given interval:
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(`Tick: ${count}`);
if (count >= 5) {
clearInterval(intervalId); // Stop after 5 ticks
}
}, 1000);setTimeout vs setInterval
| Feature | setTimeout | setInterval |
|---|---|---|
| Executes | Once | Repeatedly |
| Cancel | clearTimeout(id) | clearInterval(id) |
| Drift | No accumulation | Can drift over time |
| Guarantee | Minimum delay, not exact | Can overlap if callback is slow |
Recursive setTimeout (Better Alternative to setInterval)
// ✅ Guarantees delay BETWEEN executions
function poll() {
fetch("/api/status")
.then(res => res.json())
.then(data => {
updateUI(data);
setTimeout(poll, 5000); // Next poll after current completes
});
}
poll();
// ❌ setInterval doesn't wait for async operation
setInterval(async () => {
const data = await fetch("/api/status"); // May overlap!
}, 5000);Common Patterns
Debounce with setTimeout
let timeout;
input.addEventListener("input", () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
search(input.value);
}, 300);
});Countdown Timer
function countdown(seconds) {
const id = setInterval(() => {
console.log(seconds);
seconds--;
if (seconds < 0) {
clearInterval(id);
console.log("Done!");
}
}, 1000);
}
countdown(5);Important Gotchas
this Context
const obj = {
name: "Timer",
start() {
// ❌ Loses 'this'
setTimeout(function() {
console.log(this.name); // undefined
}, 1000);
// ✅ Arrow function preserves 'this'
setTimeout(() => {
console.log(this.name); // "Timer"
}, 1000);
}
};Minimum Delay
Browsers enforce a minimum ~4ms delay for nested timeouts (after 5 nested calls). This is specified in the HTML spec.
Important:
Always clear timers when components unmount (e.g., in React's useEffect cleanup) to prevent memory leaks. Prefer recursive setTimeout over setInterval for async operations. Remember: timer delay is a minimum, not a guarantee.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.