Timers
Objectives
By the end of this chapter, you should be able to:
- Explain why JavaScript doesn’t run top to bottom when a timer is involved
- Delay code with
setTimeout() - Repeat code with
setInterval() - Cancel a pending timer with
clearTimeout()orclearInterval()
💡 Why this matters: Timers are the simplest possible example of asynchronous code, code that doesn’t finish the moment it’s called. Everything else in this module, promises,
async/await, fetching data, all deal with the same basic idea: something that finishes later, not right now.
Delaying Code with setTimeout()
setTimeout(callback, delayInMs) schedules callback to run once, after at least delayInMs milliseconds have passed. It doesn’t pause anything, the rest of your code keeps running immediately.
console.log("1: start");
setTimeout(() => {
console.log("3: timeout fired");
}, 1000);
console.log("2: end");
This logs 1: start, then 2: end, then, a second later, 3: timeout fired. Even with a delay of 0, the timeout callback still runs after the currently running code finishes, never in the middle of it. JavaScript finishes everything it’s already doing first, then handles the timer.
Repeating Code with setInterval()
setInterval(callback, delayInMs) works like setTimeout(), except it keeps running every delayInMs milliseconds until you stop it.
let count = 0;
const id = setInterval(() => {
count++;
console.log("tick", count);
if (count === 3) {
clearInterval(id);
}
}, 1000);
This logs tick 1, tick 2, tick 3, once per second, then stops. Without that clearInterval(id) call, it would keep ticking forever.
Canceling a Timer
Both setTimeout() and setInterval() return an id, a value you can hand to clearTimeout() or clearInterval() to cancel it before it fires.
const id = setTimeout(() => {
console.log("this never prints");
}, 5000);
clearTimeout(id);
console.log("canceled before it fired");
Canceling only works before the callback runs, calling clearTimeout() after a timeout already fired does nothing (there’s nothing left to cancel). This matters most for things like a “typing…” indicator: start a timer when the user types, and cancel it if they type again before it fires.
Try It
Starter code for all three exercises:
console.log("Start");
- Add a
setTimeout()that logs"One second later"after 1000ms. Run the code and confirm"Start"logs before it. - Add a
setInterval()that logs"tick"every 500ms, and stops itself withclearInterval()after 4 ticks. - Start a
setTimeout()that logs"Too late"after 2000ms, then immediately callclearTimeout()on it. Confirm the message never logs.
Recap
setTimeout(callback, delayInMs)runscallbackonce, after at least that many milliseconds.setInterval(callback, delayInMs)runscallbackrepeatedly, every that many milliseconds, until stopped.- Both return an id.
clearTimeout(id)orclearInterval(id)cancels a pending timer, but only before it has already fired. - Code after a
setTimeout()orsetInterval()call keeps running immediately, it doesn’t wait for the timer.
Next lesson: callbacks, the pattern timers already use, and what happens when you need several of them in sequence.