HOWTO · JavaScript

在 JavaScript 中停止 setInterval 调用

本教程演示如何保存 `setInterval()` 返回的计时器标识符,并将其传给 `clearInterval()`,以停止该计时器之后的重复执行。

本页内容

调用 clearInterval(timerId) 可停止 JavaScript 计时器之后的重复执行。保存 setInterval() 返回的值,再将同一个计时器标识符传给 clearInterval()。停止按钮可以在其点击处理程序中调用该方法。

在 JavaScript 中使用 clearInterval() 停止 setInterval()

setInterval(callback, delay, ...args) 会重复调度回调,并返回一个计时器标识符。延迟时间以毫秒为单位,用来控制回调何时可以运行,但不保证每次回调都会在该时刻准时开始;其他任务可能影响调度。延迟时间之后的参数会传给每次回调调用。

下面的 Node.js 示例会打印三条更新,然后使用保存在 timerId 中的标识符清除重复计时器:

let count = 0;
const timerId = setInterval(() => {
  count += 1;
  console.log("Hello");
  if (count === 3) {
    clearInterval(timerId);
  }
}, 1000);
Hello
Hello
Hello

提供的执行结果包含这三行输出,标准错误为空,退出代码为 0。回调每次运行时都会递增 count。计数达到三次后,clearInterval(timerId) 会阻止之后已调度的回调运行。在应用程序中,只要用户仍可能需要停止该计时器,就应保留它的标识符;不要尝试根据回调或延迟时间重新构造标识符。

要添加浏览器停止按钮,可以放置一个消息元素和一个 Stop 按钮,例如 <p id="message"></p><button id="stop">Stop</button>。这些元素可用后,使用 document.querySelector("#message") 和 document.querySelector("#stop") 选中它们,然后声明 let timerId。通过 stopButton.addEventListener("click", () => clearInterval(timerId)) 注册按钮处理程序,并用 timerId = setInterval(() => { message.textContent = "Still running"; }, 1000) 设置计时器。处理程序和计时器设置必须共用同一个 timerId 变量。点击发生在设置完成之后,因此处理程序会使用返回的标识符;点击 Stop 会阻止后续更新。如果页面脚本在元素解析完成之前运行,请等 DOM 就绪后再选取元素。不可变示例中显示的按钮文字“Stop”和消息“Still running”仍为英文。

清除计时器会阻止该计时器之后的回调运行,但不会中断已经开始执行的回调,也不会撤销回调已经做出的更改。如果回调启动了异步工作,清除计时器也不会取消这项独立工作;应根据该操作自身的 API 处理取消。这一区别有助于理解为什么停止按钮看起来要等当前工作完成后才生效。

每次调用 setInterval() 都会创建一个独立的重复计时器,并返回自己的标识符。如果页面上有多个互不相关的重复任务,请分别保存各自的标识符,并根据用户执行的操作清除对应的计时器。计时器标识符不是回调函数本身。将回调、延迟时间或无关的标识符传给 clearInterval(),都无法清除你想停止的计时器。计时器清除后,再次对同一标识符调用 clearInterval() 不会产生效果。

当任务需要持续重复,直到某个操作将其停止时,可以使用 setInterval()。如果任务只需运行固定次数,请跟踪运行次数,并在达到预定次数时清除计时器,如示例所示。对于浏览器停止按钮,也可以在处理程序清除计时器后改变按钮状态或显示确认信息,让用户知道重复更新已经停止。