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
| Feature | setTimeout | setInterval |
|---|---|---|
| Execution | Runs once after delay | Runs repeatedly at set interval |
| Cancel method | clearTimeout(id) | clearInterval(id) |
| Best for | Delay a one-time task | Repeated 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 typingThrottle 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 millisecondssetInterval(fn, delay)runs a function repeatedly at every interval until cleared- Always store timer IDs in a variable to cancel them with
clearTimeout()orclearInterval() - Recursive
setTimeoutis safer thansetIntervalfor 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
