正在加载...

定时器

水壶是一个段落,#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 记下来。

hot 稍后才到

javascript
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 不会来。

烧开前取消

javascript
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,不是一直往上加。

数到三停下

javascript
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 这个词。这一段安排一个空函数,只为了看类型,然后取消它。

定时器编号

javascript
let boil = setTimeout(function () {}, 400);
console.log(typeof boil);
clearTimeout(boil);

日志是 number。

零也是稍后

延迟 0 不是「下一行之前」。回调要等这段脚本结束。水壶变成 now,这个词先被记下,然后回调才记下 later。

延迟为零

javascript
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。

页面演示 — 水壶定时器

html
<!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 是上一页。

在柜台

  1. 把水壶设成 cold,把 hot 安排在 400 毫秒后,并马上记日志。第一条是 cold。后面是 hot。
  2. 安排 hot,在它执行前调用 clearTimeout。日志停在 cold。
  3. 用 setInterval 计数,到 3 停下。日志是 3。
  4. 读编号的 typeof。日志是 number。
  5. 用延迟 0。日志先是 now,然后是 later。
  6. 读页面那一行:cold / hot / 3。

柜台上看错的地方

水壶显示的是 cold、hot 或一个计数。不是铃的那一行。

  • 以为第一条日志是 hot
  • 忘了 clearTimeout,本想取消的烧开仍然写下 hot
  • 让间隔超过 3
  • 把 400 读成 400 秒
  • 把延迟 0 当成「下一行之前」
  • 把这一行读成 same / 4 / undefined / number

记住这些

  • 下一行在超时回调之前执行
  • clearTimeout 丢掉那个回调,水壶停在 cold
  • clearInterval 把计数停在 3
  • setTimeout 的编号是数字
  • 延迟 0 仍然先记下 now,再记下 later
  • 页面这一行是 cold / hot / 3

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
7
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部