setTimeout() vs setInterval()
setTimeout() calls a function once after a set amount of time, while setInterval() calls it repeatedly until you stop it with clearInterval().
Side-by-side comparison
#How many times it calls the function
- setTimeout()
- Once, after the time elapses
- setInterval()
- Repeatedly, at the given interval
The first call
- setTimeout()
- After delay milliseconds
- setInterval()
- Also after delay, not right away
How to stop it
- setTimeout()
clearTimeout(id)before it fires- setInterval()
clearInterval(id), otherwise it runs forever
Risk of a memory leak
- setTimeout()
- Low, it only fires once
- setInterval()
- Common, a forgotten interval runs forever
When a single call takes a long time
- setTimeout()
- Doesn’t matter, there’s only one
- setInterval()
- Calls can logically overlap
Typical use
- setTimeout()
- A one-off delay, debounce
- setInterval()
- A countdown and simple background repetition
Example
#console.log('Start')
const timer = setInterval(() => console.log('Interval tick'), 200)
setTimeout(() => {
clearInterval(timer)
console.log('Timeout after 500 ms, interval stopped')
}, 500)Definition and usage
#Both functions schedule a callback after the given number of milliseconds and don’t block the rest of the code, which keeps running right away. Both return an identifier, which you pass to the matching cleanup function to cancel the scheduled call. The given time is only a minimum delay, not a guarantee of precision.
setTimeout() calls the function once and is done. setInterval() calls it repeatedly, at the same interval, until clearInterval() is called, and the first call also happens after the first interval, not right away. A forgotten interval keeps running forever, even once no one needs its results anymore, which is a common cause of memory leaks. When a single call can take longer than the interval, for example a request to a server, a self-scheduling chain of setTimeout() calls is safer.
Use setTimeout() for a one-off delay and for debounce-style mechanisms. For simple, fixed repetition, like a countdown, setInterval() is enough, but remember clearInterval() once it’s no longer needed.
Syntax
#const timeoutId = setTimeout(callback, delay)
const intervalId = setInterval(callback, delay)More examples
#let calls = 0
const id = setInterval(() => {
calls += 1
if (calls === 3) {
clearInterval(id)
console.log('Total calls:', calls)
}
}, 150)function debounce(fn, ms) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), ms)
}
}
const saveDraft = debounce((text) => console.log('Draft saved:', text), 200)
saveDraft('H')
saveDraft('He')
saveDraft('Hello')Every call to saveDraft() clears the previous timer with clearTimeout(). Only the last draft gets saved, 200 ms after the last call.
Good practices
#- Always save the identifier returned by
setInterval()and callclearInterval()once the repetition is no longer needed. - When a single call can take longer than the interval, for example a request to a server, use a chain of
setTimeout()instead ofsetInterval(). - For debounce (reacting after a pause in typing), build on
setTimeout(), notsetInterval().
Related entries
#- setTimeout()Runs a function once, after the given number of milliseconds has passed.
- setInterval()Calls a function repeatedly, at the given interval, until it’s stopped with clearInterval().
- PromiseAn object representing the result of an operation that will be available in the future: a value on success or an error.
- awaitPauses an async function until a promise settles, then returns its value or throws its error.
Spotted a mistake or missing an example? Write to us.