Timers

Schedule code to run later or repeatedly. setTimeout & setInterval.

setTimeout

Run code once after a delay.

// Basic syntax:
setTimeout(callback, delayInMs);

// Example:
setTimeout(() => {
  console.log("Hello after 2 seconds!");
}, 2000);

console.log("This runs first!");

setTimeout schedules a function to run after a specified delay (in milliseconds). Code after setTimeout runs immediately — it doesn't wait.

1 / 2

setInterval

Run code repeatedly at a fixed interval.

// Runs every 1 second:
let count = 0;
const id = setInterval(() => {
  count++;
  console.log(`Tick ${count}`);
  
  if (count >= 5) {
    clearInterval(id); // stop after 5 ticks
  }
}, 1000);

// Output (one per second):
// "Tick 1"
// "Tick 2"
// "Tick 3"
// "Tick 4"
// "Tick 5" (then stops)

💡 setInterval returns an ID you can use to stop it later with clearInterval(id). Always clear intervals when done!

Clearing Timers

Cancel scheduled timers before they fire.

// clearTimeout — cancel a one-time timer:
const timeoutId = setTimeout(() => {
  console.log("This never runs!");
}, 5000);

clearTimeout(timeoutId); // cancelled!

// clearInterval — stop a repeating timer:
const intervalId = setInterval(() => {
  console.log("tick");
}, 1000);

// Stop after 5 seconds:
setTimeout(() => {
  clearInterval(intervalId);
  console.log("Stopped!");
}, 5000);

setTimeout

Cancel with clearTimeout(id)

Runs once (if not cleared)

setInterval

Cancel with clearInterval(id)

Runs repeatedly until cleared

Timer Quirks

Timers are not precise — here's why.

// Quirk 1: Minimum delay is ~4ms (browser)
setTimeout(() => console.log("hi"), 0);
// Doesn't run at 0ms! Minimum is ~4ms
// AND it waits for the call stack to be empty

console.log("first"); // this ALWAYS runs first

setTimeout(fn, 0) doesn't mean 'run now'. It means 'run as soon as possible after current code and any pending tasks finish'.

💡 0ms delay ≠ immediate
1 / 3

Practical Patterns

Debounce and throttle — essential timer patterns.

// Debounce: wait until user STOPS doing something
function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// Only search after user stops typing for 300ms:
const search = debounce((query) => {
  fetchResults(query);
}, 300);

input.addEventListener("input", (e) => search(e.target.value));
// Throttle: run at most once per interval
function throttle(fn, interval) {
  let lastTime = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn(...args);
    }
  };
}

// Update position at most every 100ms:
window.addEventListener("scroll",
  throttle(() => updatePosition(), 100)
);

FAQ

Common questions about timers.