JavaScript
setTimeout in JavaScript - Syntax & Examples
Guide to setTimeout() in JavaScript - delayed execution, passing arguments, clearTimeout, and practical async patterns.
Syntax
const timeoutId = setTimeout(callback, delay, ...args);
| Parameter | Type | Description |
|---|---|---|
| callback | Function | The function to execute after the delay |
| delay | Number | Milliseconds to wait (default: 0) |
| ...args | Any | Optional arguments passed to the callback |
Returns a numeric timeoutId that can be passed to clearTimeout() to cancel the scheduled execution.
Basic Examples
// Simple delayed message
setTimeout(() => {
console.log('This runs after 2 seconds');
}, 2000);
// With arguments
setTimeout((name, role) => {
console.log(`Hello ${name}, you are a ${role}`);
}, 1000, 'Alice', 'developer');
// Zero delay - runs after current call stack clears
setTimeout(() => {
console.log('Runs after synchronous code');
}, 0);
console.log('This prints first');
Cancelling with clearTimeout
const id = setTimeout(() => {
console.log('This will NOT run');
}, 5000);
// Cancel before it fires
clearTimeout(id);
setTimeout with this and Classes
One of the most common pitfalls with setTimeout is losing the this context. Here are three solutions:
Problem - Lost Context
class Timer {
constructor() {
this.seconds = 0;
}
start() {
// BUG: 'this' is undefined inside setTimeout
setTimeout(function() {
this.seconds++; // TypeError!
}, 1000);
}
}
Fix 1 - Arrow Function (recommended)
class Timer {
constructor() { this.seconds = 0; }
start() {
// Arrow function inherits 'this' from parent scope
setTimeout(() => {
this.seconds++; // Works!
console.log(this.seconds);
}, 1000);
}
}
Fix 2 - bind()
start() {
setTimeout(function() {
this.seconds++;
}.bind(this), 1000);
}
Fix 3 - Variable Capture
start() {
const self = this;
setTimeout(function() {
self.seconds++;
}, 1000);
}
Practical Patterns
Debounce
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// Usage: only fire after user stops typing
const search = debounce((query) => {
fetch(`/api/search?q=${query}`);
}, 300);
input.addEventListener('input', (e) => search(e.target.value));
Polling
function poll(fn, interval) {
async function check() {
const done = await fn();
if (!done) setTimeout(check, interval);
}
check();
}
// Check order status every 5 seconds
poll(async () => {
const res = await fetch('/api/order/123');
const data = await res.json();
if (data.status === 'shipped') {
showNotification('Your order shipped!');
return true; // stop polling
}
return false;
}, 5000);
Retry with Exponential Backoff
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (err) {
if (i === retries - 1) throw err;
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, delay));
}
}
}
setTimeout vs setInterval
| Feature | setTimeout | setInterval |
|---|---|---|
| Execution | Once after delay | Repeats every interval |
| Cancel | clearTimeout(id) | clearInterval(id) |
| Drift | None (single shot) | Can accumulate |
| Recursive alternative | setTimeout inside callback | N/A |
Pro tip: Recursive setTimeout is often preferred over setInterval because it guarantees the delay between the end of one execution and the start of the next, preventing overlap if the callback takes longer than the interval.
Last updated: 2026 • Browse all courses