Discover JavaScript Timers

By

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