JavaScript Timers

JavaScript provides timer functions that schedule code to run after a delay or at regular intervals. These are essential for creating real-time features like clocks, countdowns, auto-save, and notification systems.

setTimeout — Run Code Once After a Delay

setTimeout() executes a function once after a specified number of milliseconds (1000 ms = 1 second).

Syntax:

let timerId = setTimeout(function, delayInMs, ...args);
// Show a message after 2 seconds
setTimeout(function() {
  console.log("This message appears after 2 seconds.");
}, 2000);

console.log("This appears immediately.");
// Output order:
// This appears immediately.
// (2 second pause)
// This message appears after 2 seconds.

Using Arrow Functions

setTimeout(() => {
  console.log("Arrow function in setTimeout.");
}, 1500);

Passing Arguments

function greet(name, time) {
  console.log(`Good ${time}, ${name}!`);
}

setTimeout(greet, 1000, "Arjun", "Morning");
// After 1 second: Good Morning, Arjun!

Cancelling a Timeout — clearTimeout()

let timer = setTimeout(() => {
  console.log("This will NOT run.");
}, 3000);

// Cancel before 3 seconds pass
clearTimeout(timer);
console.log("Timer cancelled!");

setInterval — Run Code Repeatedly

setInterval() executes a function repeatedly at the specified interval — until it is cancelled.

let count = 0;

let intervalId = setInterval(() => {
  count++;
  console.log("Count:", count);

  if (count === 5) {
    clearInterval(intervalId);  // Stop after 5 times
    console.log("Interval stopped.");
  }
}, 1000);

// Output every second:
// Count: 1
// Count: 2
// Count: 3
// Count: 4
// Count: 5
// Interval stopped.

Cancelling an Interval — clearInterval()

let id = setInterval(() => {
  console.log("Running every second...");
}, 1000);

// Stop after 5 seconds
setTimeout(() => {
  clearInterval(id);
  console.log("Interval cleared after 5 seconds.");
}, 5000);

setTimeout vs setInterval

FeaturesetTimeoutsetInterval
ExecutionRuns once after delayRuns repeatedly at set interval
Cancel methodclearTimeout(id)clearInterval(id)
Best forDelay a one-time taskRepeated tasks (clock, polling)

Recursive setTimeout — Better Alternative to setInterval

Using setTimeout recursively is often preferred over setInterval because the next call waits for the current one to finish before scheduling the next delay.

// setInterval can overlap if the task takes longer than the interval
// Recursive setTimeout ensures each execution completes before the next begins

let taskCount = 0;

function runTask() {
  taskCount++;
  console.log("Task", taskCount, "executed.");

  if (taskCount < 5) {
    setTimeout(runTask, 1000);  // Schedule next run only after current finishes
  }
}

runTask();

Zero Delay — setTimeout(fn, 0)

A timeout of 0 milliseconds does not run immediately — it runs after the current execution context finishes. This is useful for deferring a non-urgent task.

console.log("First");

setTimeout(() => {
  console.log("Third — deferred by setTimeout(0)");
}, 0);

console.log("Second");

// Output:
// First
// Second
// Third — deferred by setTimeout(0)

This happens because setTimeout goes through the event queue. The current synchronous code runs first.

Practical Examples

Digital Clock

<p id="clock"></p>

<script>
function updateClock() {
  let now   = new Date();
  let hours = String(now.getHours()).padStart(2, "0");
  let mins  = String(now.getMinutes()).padStart(2, "0");
  let secs  = String(now.getSeconds()).padStart(2, "0");

  document.getElementById("clock").textContent = `${hours}:${mins}:${secs}`;
}

updateClock();               // Show immediately on load
setInterval(updateClock, 1000);  // Update every second
</script>

Countdown Timer

<p id="countdown"></p>

<script>
let seconds = 10;

let timer = setInterval(() => {
  document.getElementById("countdown").textContent = `Time left: ${seconds}s`;
  seconds--;

  if (seconds < 0) {
    clearInterval(timer);
    document.getElementById("countdown").textContent = "Time is up!";
  }
}, 1000);
</script>

Auto-dismiss Notification

<div id="notification">Your profile was saved!</div>

<script>
setTimeout(() => {
  let note = document.getElementById("notification");
  note.textContent = "";
  note.style.display = "none";
}, 3000);
// Notification disappears after 3 seconds
</script>

Debounce with setTimeout

Debouncing delays a function execution until after a user stops typing. This is essential for search-as-you-type features to avoid calling the server on every keystroke.

let debounceTimer;

function handleSearch(query) {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    console.log("Searching for:", query);
    // Call API here
  }, 500);
}

// Simulate keystrokes
handleSearch("j");
handleSearch("ja");
handleSearch("jav");
handleSearch("java");
handleSearch("javascript");
// Only "javascript" triggers the search after 500ms of no typing

Throttle with setInterval

Throttling ensures a function runs at most once per specified time period — useful for scroll events or window resize handling.

let canRun = true;

function throttle(fn, delay) {
  return function(...args) {
    if (!canRun) return;
    canRun = false;
    fn(...args);
    setTimeout(() => { canRun = true; }, delay);
  };
}

const throttledScroll = throttle(() => {
  console.log("Scroll event handled:", new Date().getSeconds() + "s");
}, 1000);

window.addEventListener("scroll", throttledScroll);

Key Points to Remember

  • setTimeout(fn, delay) runs a function once after the specified milliseconds
  • setInterval(fn, delay) runs a function repeatedly at every interval until cleared
  • Always store timer IDs in a variable to cancel them with clearTimeout() or clearInterval()
  • Recursive setTimeout is safer than setInterval for tasks that may take variable time
  • setTimeout(fn, 0) defers execution to after the current code completes — it is not truly instant
  • Debouncing (setTimeout) delays a call until user stops an action — ideal for search inputs
  • Throttling (setInterval/flag) limits how often a function runs — ideal for scroll/resize events
  • Always clear intervals when a component unmounts or the feature is no longer needed to prevent memory leaks

Leave a Comment

Your email address will not be published. Required fields are marked *