JSDoc
Timers
CP2 due Wednesday at 11 pm PST
Format for documentation comments in your code
/**
* Returns the element that has the ID attribute with the specified value.
* @param {string} idName - element ID
* @returns {object} DOM object associated with id.
*/
function id(idName) {
return document.getElementById(idName);
}
JS
Required for all functions in your JS files (see the CQG)
In programs, we often want to repeat some behavior - what can we do to repeat some behavior N times? (loops!)
In simple Java/Python programs, there isn't usually motivation to delay code execution
On webpages with JavaScript, there is often motivation to delay or repeat behavior every X seconds
function startCountDown() {
let count = 10;
for (let i = count; i > 0; i--) {
console.log(i + "...");
}
console.log("0!");
}
JS
This prints a countdown to the console as soon as it's called. But what if we want to delay each line printed by 1 second?
Delaying and/or repeating functions with setTimeout/setInterval
function | description |
---|---|
setTimeout(responseFn, delayMS) | Arranges to call given function after given delayMS, returns timer id |
setInterval(responseFn, delayMS) | Arranges to call function repeatedly every delayMS ms, returns timer id |
clearTimeout(timerID)
clearInterval(timerID) |
Stops the given timer |
Both setTimeout
and setInterval
return an ID
representing the timer
window
has access to in order to manage the
page timers.
clearTimeout
/Interval
later
(e.g. when clicking a "stop timer" button)Practice: timers-practice.html
setTimeout
Example<button id="demo-btn">Click me!</button>
<span id="output-text"></span>
HTML
function init() {
id("demo-btn").addEventListener("click", delayedMessage);
}
function delayedMessage() {
id("output-text").textContent = "Wait for it...";
setTimeout(sayHello, 3000);
}
function sayHello() { // called when the timer goes off
id("output-text").textContent = "Hello!";
}
JS
output (full example page)
setInterval
Example<button id="demo-btn">Click me!</button>
<span id="output-text"></span>
HTML
let timerId = null; // stores ID of interval timer
function repeatedMessage() {
timerId = setInterval(sayHello, 1000);
}
function sayHello() {
id("output-text").textContent += "Hello!";
}
JS
output (full example page)
More details on timerId
variable on slide below
timerId
variableclearInterval/clearTimeout
or know if
we have a timer already running on our page.
clearInterval
<button id="toggle-btn">Start/Stop<button>
HTML
let timerId = null; // stores ID of interval timer
function init() {
id("toggle-btn").addEventListener("click", toggleMessageInterval);
}
// 1. What does this function do?
function toggleMessageInterval() {
if (timerId === null) {
timerId = setInterval(sayHello, 1000);
} else {
clearInterval(timerId);
timerId = null; // 2. Why is this line important?
// 3. What happens if you swap the two lines above?
}
}
function sayHello() {
id("output-text").textContent += "Hello!";
}
JS
output (full example page)
function delayedMultiply() {
// 6 and 7 are passed to multiply when timer goes off
setTimeout(multiply, 2000, 6, 7);
}
function multiply(a, b) {
alert(a * b);
}
JS
Any parameters after the delay are eventually passed to the timer function
Why not just write this?
setTimeout(multiply(6 * 7), 2000);
JS
Many students mistakenly write ()
when passing the function
setTimeout(sayHello(), 2000);
setTimeout(sayHello, 2000);
setTimeout(multiply(num1 * num2), 2000);
setTimeout(multiply, 2000, num1, num2);
JS
What does it actually do if you have the ()
?
Recall that this function prints each line immediately (in order). If we want to output each line every 1 second (1000ms), what kind of timer should we use?
function startCountDown() {
let i = 10;
setInterval(function() {
console.log(i + "...");
i--;
}, 1000);
console.log("0!");
}
JS
What's wrong here? (remember we want a 10 second countdown printed to the console)
Note that we could also replace function() { ... }
with () => { ... }
function startCountDown() {
let i = 10;
setInterval(function() {
if (i === 0) {
console.log("0!");
} else {
console.log(i + "...");
i--;
}
}, 1000);
}
JS
This is closer! But there's still something wrong...
Our timer won't stop when we reach 0!
function startCountDown() {
let i = 10;
let timerId = setInterval(function() {
if (i === 0) {
clearInterval(timerId);
// why *don't* we need to set timerId to null in this case?
console.log("0!");
} else {
console.log(i + "...");
i--;
}
}, 1000);
}
JS
This is a working solution! When startCountDown
is called, we assign
a new interval to our timer and start a 1-second countdown at 10.
When we reach 0, we need to clear the interval from the window's tasks
When you want to call a function after a specified delay in time, use
setTimeout
.
When you want to call a function repeatedly every X seconds, use
setInterval
(though you can also use setTimeout
recursively!)
For both types of timers, if you want to stop the delay/interval you'll need a variable
to keep track of the timer id (returned
by both functions) to pass to clearTimeout
/clearInterval