JS DOM: setTimeout, setInterval

By Xah Lee. Date: .
xtodo

AI generated

JavaScript Timers Tutorial: setTimeout and setInterval

setTimeout and setInterval are core browser APIs (also available in Node.js) that let you schedule code to run after a delay or at regular intervals. They are essential for animations, polling, debouncing, auto-saving, countdowns, and more.

1. setTimeout – Run Once After a Delay

const timeoutId = setTimeout(callback, delayInMilliseconds, ...args);

Basic example:

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

Passing arguments:

setTimeout((name, age) => {
  console.log(`Hello ${name}, you are ${age}`);
}, 1000, "Alice", 30);

2. setInterval – Run Repeatedly Every Interval

const intervalId = setInterval(callback, delayInMilliseconds, ...args);

Same parameters as setTimeout, but the callback runs every delay milliseconds until cleared.

Example:

let count = 0;
const intervalId = setInterval(() => {
  count++;
  console.log(`Count: ${count}`);

  if (count >= 5) {
    clearInterval(intervalId);
    console.log("Stopped");
  }
}, 1000);

3. Clearing Timers

clearTimeout(timeoutId);
clearInterval(intervalId);

Important: You can call clearTimeout on an interval ID and vice versa (they share the same ID pool), but it's best practice to use the matching clear function.

Example of canceling:

const id = setTimeout(() => console.log("This won't run"), 5000);

// Cancel immediately
clearTimeout(id);

4. Complete Practical Examples

Countdown Timer

let timeLeft = 10;

const countdown = setInterval(() => {
  console.log(timeLeft);
  timeLeft--;

  if (timeLeft < 0) {
    clearInterval(countdown);
    console.log("Time's up!");
  }
}, 1000);

Simple Animation (moving a box)

<div id="box" style="position:absolute; width:50px; height:50px; background:red;"></div>

<script>
const box = document.getElementById('box');
let position = 0;

const animate = setInterval(() => {
  position += 5;
  box.style.left = position + 'px';

  if (position > 500) clearInterval(animate);
}, 20); // ~50fps
</script>

Debouncing User Input (common in search boxes)

let timeout;
const input = document.getElementById('search');

input.addEventListener('input', () => {
  clearTimeout(timeout); // cancel previous

  timeout = setTimeout(() => {
    console.log("Searching for:", input.value);
    // perform expensive search
  }, 300); // wait until user stops typing
});

5. Key Concepts & Gotchas

this binding The callback loses its this context unless you use an arrow function or .bind().

const obj = {
  name: "Bob",
  greet() {
    console.log(this.name);
  }
};

// Wrong - this becomes window/global
setTimeout(obj.greet, 1000);

// Correct ways:
setTimeout(() => obj.greet(), 1000);
setTimeout(obj.greet.bind(obj), 1000);

Minimum delay and throttling Browsers clamp delays below 4ms to 4ms for setTimeout/setInterval when called from the main thread after the first execution. Nested timers have even higher minimums (for security/performance).

Not precise timing Timers are not guaranteed to fire exactly on time. They are scheduled when the event loop is free. Heavy computation or long tasks delay them.

Node.js vs Browser

Modern alternatives

6. Promise-based Version (Useful for async/await)

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

// Usage
async function run() {
  console.log("Start");
  await delay(2000);
  console.log("After 2s");
}

7. Best Practices

  1. Always store and clear timer IDs when possible.
  2. Use arrow functions for simple callbacks to preserve this.
  3. Prefer requestAnimationFrame over setInterval for UI animations.
  4. For very long-running intervals, consider Web Workers.
  5. Be careful with memory leaks β€” uncleared intervals in components (especially React/Vue) are common bugs.
  6. In React, clean up timers in useEffect return function.

Quick Reference

Feature setTimeout setInterval
Runs Once Repeatedly
Cancel with clearTimeout clearInterval
Typical use Delayed action Polling, animation
Returns Timer ID Timer ID

Would you like me to expand this tutorial with:

Just let me know!