setTimeout and setInterval ExplainedJavaScript timing functions schedule code to run after a delay or on a repeating interval without blocking the main thread. setTimeout(fn, ms) runs a callback once after at least ms milliseconds, whereas setInterval(fn, ms) schedules it repeatedly until cleared.
The millisecond delay passed to setTimeout(fn, 100) is a minimum wait time, never an exact alarm. When the timer expires, the callback enters the Event Loop task queue and waits until any currently running synchronous code and microtasks finish.
Also note that browsers throttle background tab timers to once per second (1000ms) or slower to save laptop and phone battery.
Always save the numeric timer ID returned by setTimeout() or setInterval() so you can cancel pending work with clearTimeout() or clearInterval(). For recurring async API polling, prefer recursive setTimeout() inside finally so requests never overlap if one takes longer than the interval.
// One-time delayed message with cancel capability
const timeoutId = setTimeout(() => {
console.log("One-shot timer executed after ~30ms");
}, 30);
// Cancel example (uncomment to abort before 30ms):
// clearTimeout(timeoutId);
// Repeating interval that cleans itself up after 3 ticks
let ticks = 0;
const intervalId = setInterval(() => {
ticks += 1;
console.log(`Interval tick #${ticks}`);
if (ticks >= 3) {
clearInterval(intervalId);
console.log("Interval cleared cleanly.");
}
}, 20);
setTimeout("doWork()", 500) evaluates the string like eval(), creating security risks and Content Security Policy errors. Always pass a function reference.setInterval(fetchData, 1000): If fetchData() takes 1.5 seconds on slow Wi-Fi, multiple requests stack up out of order. Schedule the next setTimeout only after the previous request finishes.clearInterval() on cleanup: Leaving intervals alive after closing a widget leaks memory and wastes network calls.0 milliseconds to setTimeout(fn, 0)?It queues fn to run asynchronously after the current synchronous call stack and all pending Promise microtasks complete—useful for yielding to the browser before heavy work.
setTimeout callback?Pass them after the delay (setTimeout(greet, 100, "Ada")) or wrap them cleanly in an arrow function (setTimeout(() => greet("Ada"), 100)).
setTimeout(..., 0) run after Promise.resolve().then(...)?Promises use the high-priority microtask queue, which the Event Loop drains completely before taking the next setTimeout task from the macrotask queue.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.