定时器
水壶是一个段落,#pot。脚本往里面写 cold。这一页没有表单,也没有店铃。
定时器不会让脚本停住。下一行马上执行。回调稍后才执行。400 毫秒的超时写下 hot。取消它,水壶就停在 cold。间隔数 1、2、3 然后停下。这一行是 cold / hot / 3。
不是那只铃
上一页拼的是 same / 4 / undefined / number。那是文档、一个 var、一个 let,还有宽度的类型。这一页不读那些。cold 和 hot 是定时器写到水壶上的词。
新的问题是:这个词什么时候变。
下一行不等
setTimeout 要一个函数,还要一个以毫秒计的延迟。400 是十分之四秒,不是 400 秒。调用下面的那条日志先出来,水壶还是 cold。回调稍后写下 hot,再把 hot 记下来。
let pot = document.getElementById("pot");
pot.textContent = "cold";
setTimeout(function () {
pot.textContent = "hot";
console.log(pot.textContent);
}, 400);
console.log(pot.textContent);
第一条日志是 cold。后面那条是 hot。脚本没有在原地坐满 400 毫秒。
取消烧开
setTimeout 返回一个编号。用这个编号调用 clearTimeout,回调就被丢掉。水壶已经是 cold,hot 不会来。
let pot = document.getElementById("pot");
pot.textContent = "cold";
let boil = setTimeout(function () {
pot.textContent = "hot";
}, 400);
clearTimeout(boil);
console.log(pot.textContent);
日志是 cold。回调丢掉了,水壶不会变成 hot。
倒三次
setInterval 一次次调用函数,这里每 300 毫秒一次。每次加一。到 3,clearInterval 停下。日志是这个 3,不是一直往上加。
let pot = document.getElementById("pot");
let n = 0;
let tick = setInterval(function () {
n = n + 1;
pot.textContent = String(n);
if (n === 3) {
clearInterval(tick);
console.log(pot.textContent);
}
}, 300);
日志是 3。间隔的编号是 tick。没有 clearInterval,数字还会继续涨。
编号是数字
setTimeout 返回的值是数字。不是延迟,也不是 hot 这个词。这一段安排一个空函数,只为了看类型,然后取消它。
let boil = setTimeout(function () {}, 400);
console.log(typeof boil);
clearTimeout(boil);
日志是 number。
零也是稍后
延迟 0 不是「下一行之前」。回调要等这段脚本结束。水壶变成 now,这个词先被记下,然后回调才记下 later。
let pot = document.getElementById("pot");
pot.textContent = "now";
setTimeout(function () {
console.log("later");
}, 0);
console.log(pot.textContent);
第一条日志是 now。第二条是 later。零没有插队。
延迟是什么意思
单位是毫秒。水壶那一行就是这一页用的。
📊 延迟是什么意思
| 延迟 | 意思 | 容易混 |
|---|---|---|
| 0 | 这段脚本结束后 | 下一行之前 |
| 400 | 0.4 秒 | 400 秒 |
| 1000 | 一秒 | 一分钟 |
水壶下面的那一行
脚本写下 cold,并马上存下这个词。400 毫秒的超时存下 hot。间隔每 300 毫秒加一,到 3 停下,再把三个词接起来。hot 比第三次倒水更早存下,因为 400 小于 900。
<!DOCTYPE html>
<html>
<head>
<title>kettle-timer — page</title>
</head>
<body>
<p id="pot">blank</p>
<p id="line">…</p>
<script>
let pot = document.getElementById("pot");
let seen = [];
pot.textContent = "cold";
seen.push(pot.textContent);
setTimeout(function () {
pot.textContent = "hot";
seen.push("hot");
}, 400);
let n = 0;
let tick = setInterval(function () {
n = n + 1;
if (n === 3) {
clearInterval(tick);
seen.push(String(n));
document.getElementById("line").textContent = seen.join(" / ");
}
}, 300);
</script>
</body>
</html>
这一行是 cold / hot / 3。cold 是马上的。hot 来自超时。3 来自间隔。blank 没了。same / 4 / undefined / number 是上一页。
在柜台
- 把水壶设成 cold,把 hot 安排在 400 毫秒后,并马上记日志。第一条是 cold。后面是 hot。
- 安排 hot,在它执行前调用
clearTimeout。日志停在 cold。 - 用
setInterval计数,到 3 停下。日志是 3。 - 读编号的
typeof。日志是 number。 - 用延迟 0。日志先是 now,然后是 later。
- 读页面那一行:cold / hot / 3。
柜台上看错的地方
水壶显示的是 cold、hot 或一个计数。不是铃的那一行。
- 以为第一条日志是 hot
- 忘了
clearTimeout,本想取消的烧开仍然写下 hot - 让间隔超过 3
- 把 400 读成 400 秒
- 把延迟 0 当成「下一行之前」
- 把这一行读成 same / 4 / undefined / number
记住这些
- 下一行在超时回调之前执行
clearTimeout丢掉那个回调,水壶停在 coldclearInterval把计数停在 3setTimeout的编号是数字- 延迟 0 仍然先记下 now,再记下 later
- 页面这一行是 cold / hot / 3
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部