Discover JavaScript Timers
By Flavio Copes
Learn how setTimeout and setInterval schedule JavaScript tasks, cancel timers, handle timing delays, and avoid overlapping asynchronous work.
JavaScript timers schedule a function to run later.
Use setTimeout() to run it once. Use setInterval() to request repeated runs.
The delay is a minimum, not an exact appointment. A callback can run later when the main thread is busy or the browser throttles the page.
Run code later with setTimeout
Pass a function and a delay in milliseconds:
setTimeout(() => {
console.log('Two seconds passed')
}, 2000)
setTimeout() returns a timer ID. Save it when you might cancel the timer:
const timerId = setTimeout(() => {
console.log('Saved')
}, 2000)
clearTimeout(timerId)
Calling clearTimeout() after the callback has already run has no effect.
You can pass arguments after the delay:
function greet(name) {
console.log(`Hello ${name}`)
}
setTimeout(greet, 1000, 'Flavio')
I usually prefer a small arrow function when it makes the call easier to read:
setTimeout(() => greet('Flavio'), 1000)
Always pass a function. Passing a string makes the browser evaluate code and creates the same security problems as eval().
What a zero delay means
A delay of 0 does not run the callback immediately:
setTimeout(() => {
console.log('timer')
}, 0)
console.log('current task')
The result is:
current task
timer
The current task must finish first. Promise callbacks and other microtasks also run before the browser takes the timer task from its queue.
A zero-delay timer can move work to a later task. It cannot make a long calculation cheap. Break CPU-heavy work into small pieces or move it to a Web Worker.
Browsers also clamp deeply nested timers to a minimum delay. Do not depend on repeated zero-delay timers for precise scheduling.
Repeat code with setInterval
setInterval() requests another callback after each interval:
const intervalId = setInterval