Sometimes code shouldn't run right now. You might want to show a message for three seconds, update a clock every second, or wait until someone stops typing before running a search. JavaScript's timers, setTimeout and setInterval, handle all of these.
Timers are also your first taste of asynchronous code: code that's scheduled to run later while the rest of the program carries on. Understanding how timers behave makes the later lessons on Promises and async/await much easier.
setTimeout: run once, later
const id = setTimeout(() => {
console.log("3 seconds later");
}, 3000);- The first argument is the function to run.
- The second is the delay in milliseconds, where 1000ms is one second.
- It returns an id you can use to cancel the timer:
clearTimeout(id).
Pass the function itself, not the result of calling it. setTimeout(showMessage(), 3000) runs showMessage immediately.
setInterval: run again and again
const id = setInterval(() => {
console.log("tick");
}, 1000);
clearInterval(id); // stop itAlways keep the id so you can stop the interval later. An interval with no way to stop it runs until the visitor leaves the page, which wastes battery and can pile up if you accidentally start it twice.
Timers don't pause your code
JavaScript doesn't wait at a setTimeout. It schedules the function and carries straight on to the next line. Even setTimeout(fn, 0) runs after the current code has finished. This "asynchronous" behaviour is the foundation of Promises and async/await.
The delay is also a minimum, not a guarantee. If the browser is busy, or the tab is in the background, the function may run later than requested. For an accurate clock, read the current time with new Date() on each tick rather than counting ticks.
Passing arguments and cleaning up
Extra arguments after the delay are passed to your function: setTimeout(greet, 1000, "Ana") calls greet("Ana") after one second. Most people find an arrow function clearer: setTimeout(() => greet("Ana"), 1000).
Timers keep running until they finish or you cancel them, even if the part of the page they update has been removed. In bigger apps, always clear intervals when a component closes or a user navigates away, otherwise they keep using memory and battery, and may try to update elements that no longer exist. For animation, use requestAnimationFrame instead of a fast interval, as shown in the canvas lesson.
JavaScript Timers Syntax
Timers
const t = setTimeout(fn, 1000); // run once after 1s
clearTimeout(t); // cancel it
const i = setInterval(fn, 500); // run every 0.5s
clearInterval(i); // stop itJavaScript Timers Summary
setTimeoutruns a function once after a delay in milliseconds.setIntervalruns a function repeatedly at a fixed interval.- Both return an id; use
clearTimeoutorclearIntervalto cancel. - Timers are asynchronous: the rest of your code keeps running.
- Debouncing waits for a pause before running code, such as a search.
JavaScript Timers Examples
Each example runs in the page. Edit the code and press Run to see what changes.
Order of execution
Predict the order before you press Run.
console.log("1. Start");
setTimeout(() => {
console.log("3. Timeout finished");
}, 1000);
setTimeout(() => {
console.log("2.5. Zero-delay timeout");
}, 0);
console.log("2. End of script");Line-by-line explanation
- Line 1Runs immediately.
- Lines 3 to 5Scheduled for 1 second later. The script doesn't wait.
- Lines 7 to 9Even with 0ms, it waits until the current script is finished.
- Line 11Runs before both timeouts.
A countdown
<h2 id="clock">5</h2>
<button id="go">Start countdown</button>const clock = document.querySelector("#clock");
const go = document.querySelector("#go");
go.addEventListener("click", () => {
let seconds = 5;
clock.textContent = seconds;
go.disabled = true;
const timer = setInterval(() => {
seconds--;
clock.textContent = seconds > 0 ? seconds : "🚀 Liftoff!";
if (seconds === 0) {
clearInterval(timer);
go.disabled = false;
}
}, 1000);
});Line-by-line explanation
- Line 9Run every second and keep the id.
- Lines 10 to 11Count down and update the page.
- Lines 12 to 15At zero, stop the interval and re-enable the button.
Debounced search
Type quickly. The "search" only runs once you pause.
<input id="search" placeholder="Search recipes…">
<p id="status">Start typing…</p>const search = document.querySelector("#search");
const status = document.querySelector("#status");
let timer;
search.addEventListener("input", () => {
clearTimeout(timer);
status.textContent = "Typing…";
timer = setTimeout(() => {
status.textContent = `Searching for "${search.value}"`;
console.log("Search sent:", search.value);
}, 400);
});Line-by-line explanation
- Line 3Remember the latest timeout id between keystrokes.
- Line 6Each keystroke cancels the previous scheduled search…
- Lines 8 to 11…and schedules a new one 400ms later. Only the last one survives.
Common JavaScript Timers Mistakes
Calling the function instead of passing it
setTimeout(showMessage(), 2000); // runs immediatelysetTimeout(showMessage, 2000);
setTimeout(() => showMessage("Hi"), 2000);Seconds instead of milliseconds
setTimeout(save, 5); // 5 milliseconds, not 5 secondssetTimeout(save, 5000);Never clearing an interval
button.addEventListener("click", () => {
setInterval(tick, 1000); // every click starts another one!
});let timer;
button.addEventListener("click", () => {
clearInterval(timer);
timer = setInterval(tick, 1000);
});JavaScript Timers in Real Projects
Timers in everyday interfaces
Toast notifications that disappear after a few seconds, auto-saving drafts, slideshows, typing indicators, session timeouts, the countdown on an OTP code, and debounced search boxes all rely on timers.
JavaScript Timers Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Log "Hi" once after 2 seconds.
(() => console.log("Hi"), );
In what order are the letters logged?
setTimeout(() => console.log("A"), 0);
console.log("B");
setTimeout(() => console.log("C"), 0);
console.log("D");How do you stop an interval?
This should log tick exactly 3 times and then done, but it never stops. Fix it.
let count = 0;
setInterval(() => {
count++;
console.log("tick");
if (count === 3) {
console.log("done");
}
}, 100);- Ticks exactly 3 times then done
JavaScript Timers Quiz
3 questions to check what you learned.
What unit is the delay in setTimeout?
- Seconds
- Minutes
- Frames
- Milliseconds
Does
setTimeoutpause the rest of your code?- No. It schedules the function and the code continues immediately
- Yes
- Only for long delays
- Only in loops
What is debouncing?
- Running code faster
- Waiting until events stop for a moment before running code
- Repeating code forever
- Removing bugs automatically
JavaScript Timers Challenge
Toast notification
When #save is clicked:
- Show
#toastby adding the classshow - After 1500ms, remove the
showclass - If the button is clicked again before it hides, restart the timer (use
clearTimeout)
<button id="save">Save</button>
<div id="toast">✅ Saved!</div>
<style>
#toast { opacity: 0; transition: opacity 0.2s; }
#toast.show { opacity: 1; }
</style>const save = document.querySelector("#save");
const toast = document.querySelector("#toast");
- Clicking shows the toast
- It hides after about 1.5s
- Uses clearTimeout