JavaScript's timer functions let you schedule code to run later or repeatedly, without blocking the rest of the program while waiting. This lesson covers setTimeout and clearTimeout for one-time delays, setInterval and clearInterval for repeating tasks, why setTimeout(fn, 0) still waits for the current call stack to clear, and the recursive setTimeout pattern as an alternative to setInterval.
1JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 1
Welcome! Today we' Ypu'll master Timers in JavaScript: how to delay code and how to run it repeatedly.
// Timing & Scheduling2JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 2
The ' 'setTimeout' function executes a piece of code ONCE after a specified delay in milliseconds.
setTimeout(() => {
console.log('1 second passed!');
}, 1000);3JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 3
It returns a Timeout ID. You can use this ID to cancel the execution before it happens using ' 'clearTimeout'.
const timerId = setTimeout(() => console.log('Wait...'), 5000);
clearTimeout(timerId); // Cancelled!4JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 4
If you need code to run REPEATEDLY, use ' 'setInterval'. It keeps firing until you stop it.
const intervalId = setInterval(() => {
console.log('Tick...');
}, 1000);5JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 5
Stopping an interval is crucial to prevent memory leaks. Always use ' 'clearInterval' with the interval ID.
clearInterval(intervalId);
console.log('Ticking stopped.');6JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 6
Pro Tip: setTimeout with 0ms delay doesn' It doesn't run immediately. It pushes the task to the END of the current execution queue.
console.log('A');
setTimeout(() => console.log('B'), 0);
console.log('C');
// Output: A, C, B7JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 7
Recursive setTimeout is often better than setInterval for complex tasks, as it waits for the current task to finish before scheduling the next one.
function repeat() {
doComplexWork();
setTimeout(repeat, 1000);
}
repeat();8JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 8
Summary: Use setTimeout for single delays and setInterval for loops. Always clear your timers!
<h1>Timers: Controlled</h1>9JavaScript Timers & Asynchronous Scheduling | JS Tutorial - In-Depth Guide Part 9
Timing and Scheduling mastered! You can now build clocks, animations, and polling systems.
<h1>Scheduling: Mastered</h1>10Step-by-Step Breakdown
Welcome! Today we' Ypu'll master Timers in JavaScript: how to delay code and how to run it repeatedly.
The ' 'setTimeout' function executes a piece of code ONCE after a specified delay in milliseconds.
It returns a Timeout ID. You can use this ID to cancel the execution before it happens using ' 'clearTimeout'.
Checkpoint: How many milliseconds are in 2 seconds for a setTimeout delay?
- ā2
- ā200
- ā2000
If you need code to run REPEATEDLY, use ' 'setInterval'. It keeps firing until you stop it.
Stopping an interval is crucial to prevent memory leaks. Always use ' 'clearInterval' with the interval ID.
Checkpoint: Which function is used to stop a repeating setInterval task?
- āstopInterval()
- āclearInterval()
- ādeleteInterval()
Pro Tip: setTimeout with 0ms delay doesn' It doesn't run immediately. It pushes the task to the END of the current execution queue.
Recursive setTimeout is often better than setInterval for complex tasks, as it waits for the current task to finish before scheduling the next one.
Summary: Use setTimeout for single delays and setInterval for loops. Always clear your timers!
Final Challenge: If you call setTimeout(fn, 1000) and then immediately call clearTimeout(id), will 'fn' ever run?
- āYes, once
- āNo, it is removed from the queue
Timing and Scheduling mastered! You can now build clocks, animations, and polling systems.
Level Up š
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Avoid Timer-Driven Content Changes That Auto-Update Without User Control
Content that refreshes or moves on a setInterval (like a rotating carousel or auto-advancing slideshow) can violate WCAG 2.2.2 (Pause, Stop, Hide) if there's no way for the user to pause it; always pair timer-driven UI updates with an accessible pause/stop control.
SEO Implications
- 1
Long-Running or Leaked Intervals Degrade Interaction Metrics That Affect Search Ranking
An interval that's never cleared keeps consuming CPU in the background for as long as the page is open, which can degrade Interaction to Next Paint and overall responsiveness ā both of which are Core Web Vitals signals that factor into search ranking.
Best Practices
Always Store and Clear Timer IDs When the Work Is No Longer Needed
Every setTimeout or setInterval call returns an ID; keep a reference to it and call clearTimeout/clearInterval when the relevant component unmounts or the condition triggering the timer no longer applies, to avoid leaked callbacks running against stale state.
Prefer requestAnimationFrame Over setInterval for Visual Animations
setInterval fires on a fixed clock regardless of whether the browser is ready to paint, which can cause dropped or stuttering frames; requestAnimationFrame synchronizes callbacks with the browser's actual repaint cycle, producing smoother animations and pausing automatically on background tabs.
Frequent Bugs
A setInterval-based polling loop keeps running and consuming resources after the component or page section using it is removed.
Always capture the return value of setInterval and call clearInterval(id) in a cleanup function (e.g. a React useEffect cleanup, or an explicit teardown method) so the timer is stopped exactly when the surrounding UI goes away.
A setInterval callback that takes longer to execute than the interval itself causes overlapping or backed-up executions.
setInterval doesn't wait for a slow callback to finish before scheduling the next one, so slow work can pile up. Switch to a recursive setTimeout pattern instead, which only schedules the next run after the current one completes, guaranteeing a minimum gap between executions.
Real-World Examples
Polling an API for Status Updates with Recursive setTimeout
A file-upload progress page needed to check a server endpoint for status updates every few seconds, but only after each check actually finished, to avoid piling up overlapping requests if the server responded slowly.
function pollStatus() {
fetch('/api/upload-status')
.then(res => res.json())
.then(data => {
updateUI(data);
if (data.status !== 'complete') {
setTimeout(pollStatus, 3000);
}
});
}
pollStatus();