You will be able to delay code once with setTimeout and repeat code with setInterval, then stop timers safely.
What it is
JavaScript timers let you schedule a function to run later. setTimeout schedules one callback after a delay. setInterval schedules a callback to run repeatedly at a fixed interval. Both return a timer ID that can be passed to clearTimeout or clearInterval to cancel the scheduled work.
The mental model is a queue: the browser or Node runtime waits for the delay, then places the callback into the event loop. The callback runs when the current code finishes and the queue is processed. Related terms include callback, delay, timer ID, event loop, and cancellation.
Why it matters
- Show a message after a short pause, such as a toast or loading hint.
- Poll a value periodically, such as checking a status every few seconds.
- Debounce or throttle user input by delaying work until activity settles.
- Stop repeating work when a component unmounts or a task finishes.
- Coordinate simple animations or countdowns without blocking the main thread.
Syntax or steps
The smallest useful pattern is a function, a delay in milliseconds, and optional cancellation:
const id = setTimeout(callback, delay);
clearTimeout(id);
const intervalId = setInterval(callback, delay);
clearInterval(intervalId);
Use a function reference or arrow function, not a string. A delay of 0 means “as soon as possible,” not immediate. Intervals continue until cleared, so always store the ID when you need to stop them.
Example
let ticks = 0;
const intervalId = setInterval(() => {
ticks += 1;
console.log(`tick ${ticks}`);
if (ticks === 3) {
clearInterval(intervalId);
console.log("interval stopped");
}
}, 500);
const delayedId = setTimeout(() => {
console.log("delayed message after 1 second");
}, 1000);
setTimeout(() => {
clearTimeout(delayedId);
console.log("cleanup attempted");
}, 2000);
setIntervallogs a tick every 500 milliseconds.- The callback increments
ticksand stops itself after three ticks. setTimeoutlogs one delayed message after 1000 milliseconds.- The final timer runs after 2000 milliseconds and tries to clear the earlier timeout, which has already fired.
Common mistakes
- Assuming exact timing. Timers are minimum delays, not guarantees. Fix by treating them as approximate and using
requestAnimationFramefor smooth visual updates. - Forgetting to clear intervals. An interval can keep running after its data is no longer needed. Fix by storing the ID and clearing it in cleanup code.
- Passing a string.
setTimeout("doWork()", 1000)is unsafe and slower. Fix by passing a function:setTimeout(doWork, 1000). - Blocking the event loop. A long synchronous loop delays all timers. Fix by breaking work into smaller chunks or using async patterns.
When to use it
| Need | Use | Why |
|---|---|---|
| Run once after a delay | setTimeout | Simple one-shot scheduling. |
| Run repeatedly at fixed intervals | setInterval | Convenient for polling or countdowns. |
| Repeat with more control over drift | Recursive setTimeout | Each delay starts after the previous callback finishes. |
| Smooth animation | requestAnimationFrame | Synchronizes with the browser refresh cycle. |
Practice
Guided exercise: Write a timer that logs "ready" after 2 seconds, then logs "done" after 5 seconds.
setTimeout(() => console.log("ready"), 2000);
setTimeout(() => console.log("done"), 5000);
Challenge: Create a countdown from 3 to 1 using setInterval, then clear it and log "go".
Hint: Start at 3, decrement each tick, and call clearInterval when the value reaches 0.
Quick check
What must you do to stop a repeating timer?
Store the ID returned by setInterval and pass it to clearInterval.
Summary
Timers schedule work for later: setTimeout for one delay and setInterval for repetition. They are approximate, so always clear intervals and avoid relying on exact timing.