JavaScript 定时器
JavaScript 定时器事件
Section titled “JavaScript 定时器事件”JavaScript 可以在指定的延迟后或以固定的时间间隔执行代码。这些通常被称为定时器事件(timing events)或定时操作(timed operations)。
JavaScript 定时函数
Section titled “JavaScript 定时函数”JavaScript 提供了内置函数,允许你安排代码的执行。你可以在经过一定时间后执行函数一次,或者以设定的间隔重复执行。
两个关键的方法是:
setTimeout(callbackFunction, delayInMilliseconds, arg1, arg2, ...):在经过delayInMilliseconds后,执行callbackFunction一次。可选参数arg1, arg2, ...将传递给回调函数。setInterval(callbackFunction, intervalInMilliseconds, arg1, arg2, ...):重复执行callbackFunction,每次执行之间间隔intervalInMilliseconds。可选参数也会传递给回调函数。
注意:setInterval() 和 setTimeout() 在浏览器中是全局 window 对象的方法(在 Node.js 等环境中是全局作用域的方法)。在浏览器环境中,你无需 window. 前缀即可直接调用它们(例如,setTimeout(...))。
这些函数是非阻塞的(non-blocking)。这意味着 JavaScript 在等待定时器时不暂停;它可以继续执行其他代码。回调函数被添加到事件队列 (event queue) 中,并在定时器到期且 JavaScript 引擎的调用栈 (call stack) 为空(即主线程 free)时执行。
setInterval() 方法
Section titled “setInterval() 方法”setInterval() 方法重复调用一个函数或执行一段代码片段,在每次调用之间有固定的时间延迟。
// 首选语法:传递函数引用let intervalID = setInterval(myFunction, 2000);
// 匿名函数示例:let intervalID_anon = setInterval(function() { console.log("Executing every 2 seconds");}, 2000);
// 箭头函数示例 (现代且简洁):let intervalID_arrow = setInterval(() => { console.log("Arrow function executing every 2 seconds");}, 2000);
// 向回调函数传递参数:function greet(name) { console.log(`Hello, ${name}!`);}let greetInterval = setInterval(greet, 1500, "Alice");
// 要停止这些定时器,你可以调用:clearInterval(intervalID);参数:
callbackFunction:要每隔intervalInMilliseconds执行的函数。intervalInMilliseconds:计时器在执行指定函数之间应延迟的时间,以毫秒(千分之一秒)为单位。1000 毫秒等于 1 秒。arg1, arg2, ...:可选的额外参数,传递给callbackFunction。
setInterval() 返回一个数字型的间隔 ID (interval ID),可以使用 clearInterval() 来停止该间隔定时器。
关键在于将实际的函数(函数引用、匿名函数或箭头函数)作为第一个参数传递。传递字符串形式的代码(例如,setInterval("myFunction()", 1000))是一种过时且不安全的做法,它内部使用了 eval(),强烈不推荐。
一个实际的用例是更新动态内容,比如时钟:
// 假设你有一个 HTML 元素,例如:<p id="clock"></p>
function displayTime() { const now = new Date(); const timeString = now.toLocaleTimeString(); const clockElement = document.getElementById("clock"); if (clockElement) { clockElement.textContent = timeString; }}
// 立即调用 displayTime 一次,以便在没有延迟的情况下显示时间// displayTime();
// 然后每秒更新一次。运行此代码前,确保 HTML 元素存在。// const clockInterval = setInterval(displayTime, 1000);
// 要停止时钟(例如,如果用户离开页面或点击了某个按钮):// clearInterval(clockInterval);在实际应用中,你通常会将 displayTime 调用和 setInterval 放在一个脚本中,该脚本在浏览器加载了 id='clock' HTML 元素后运行,或者使用像 DOMContentLoaded 这样的事件监听器。
如何停止执行 (clearInterval)
Section titled “如何停止执行 (clearInterval)”要停止由 setInterval() 设置的间隔定时器,可以使用 clearInterval() 方法。它接受 setInterval() 返回的间隔 ID 作为参数。
clearInterval(intervalID);要使用 clearInterval(),你必须将 setInterval() 返回的 ID 存储在一个变量中。这个变量不一定需要是全局的,但它必须在调用 clearInterval() 的作用域 (scope) 中可访问。
// 此示例所需的 HTML:// <p id="timerDisplay">Loading...</p>// <button id="stopButton">Stop Timer</button>
/*const timerDisplayElement = document.getElementById("timerDisplay");const stopButtonElement = document.getElementById("stopButton");let timerIntervalID;
function updateTimerDisplay() { const now = new Date(); if (timerDisplayElement) { timerDisplayElement.textContent = now.toLocaleTimeString(); }}
if (timerDisplayElement) { updateTimerDisplay(); timerIntervalID = setInterval(updateTimerDisplay, 1000);}
if (stopButtonElement) { stopButtonElement.addEventListener('click', function() { clearInterval(timerIntervalID); if (timerDisplayElement) { timerDisplayElement.textContent = "定时器已停止。"; } console.log("定时器已通过按钮停止。"); });}*/上面注释掉的代码演示了如何设置一个间隔定时器,然后使用按钮清除它。使用 addEventListener 是处理事件的现代方式。
setTimeout() 方法
Section titled “setTimeout() 方法”setTimeout() 方法在指定的延迟后执行一个函数或代码片段一次。
// 首选语法:传递函数引用let timeoutID = setTimeout(myDelayedFunction, 3000);
// 匿名函数示例:let timeoutID_anon = setTimeout(function() { console.log("Executed after 3 seconds");}, 3000);
// 箭头函数示例:let timeoutID_arrow = setTimeout(() => { console.log("Arrow function executed after 3 seconds");}, 3000);
// 传递参数:function showMessage(message, type) { console.log(`[${type.toUpperCase()}]: ${message}`);}let messageTimeout = setTimeout(showMessage, 2000, "Operation complete", "info");
// 在执行前取消这些定时器:clearTimeout(timeoutID);参数:
callbackFunction:在delayInMilliseconds后要执行的函数。delayInMilliseconds:等待的时间,以毫秒为单位,之后执行函数。arg1, arg2, ...:可选的额外参数,传递给callbackFunction。
setTimeout() 返回一个数字型的定时器 ID (timeout ID),可以使用 clearTimeout() 在它执行前取消该定时器。
与 setInterval() 一样,始终将实际的函数作为第一个参数传递,而不是字符串形式的代码。
// 所需 HTML:<button id="myButton">Greet after 3s</button>/*const myButton = document.getElementById('myButton');if (myButton) { myButton.addEventListener('click', function() { console.log("Button clicked. Greeting will appear in 3 seconds..."); setTimeout(function() { console.log("Hello there!"); // 或者:如果需要弹窗,可以使用 alert("Hello there!"); }, 3000); });}*/如何取消定时器 (clearTimeout)
Section titled “如何取消定时器 (clearTimeout)”如果你想阻止一个计划执行的函数(例如,如果用户执行了另一个操作,使得定时器变得不必要),你可以使用 clearTimeout()。它接受 setTimeout() 返回的定时器 ID 作为参数。
clearTimeout(timeoutID);要使用 clearTimeout(),你必须将 setTimeout() 返回的 ID 存储在一个在调用 clearTimeout() 的作用域中可访问的变量里。
如果在计时器到期之前调用 clearTimeout(),则计划的函数将不会执行。
// 所需 HTML:// <button id="startButton">Start 3s Timeout</button>// <button id="cancelButton">Cancel Timeout</button>// <p id="statusMessage"></p>/*const startBtn = document.getElementById('startButton');const cancelBtn = document.getElementById('cancelButton');const statusMsg = document.getElementById('statusMessage');let scheduledAlertID;
if (startBtn && cancelBtn && statusMsg) { startBtn.addEventListener('click', function() { statusMsg.textContent = "Timeout scheduled. Alert in 3 seconds."; if (scheduledAlertID) { clearTimeout(scheduledAlertID); } scheduledAlertID = setTimeout(function() { alert('Hello from timeout!'); statusMsg.textContent = "Alert displayed!"; scheduledAlertID = null; // 执行后清除 ID }, 3000); });
cancelBtn.addEventListener('click', function() { if (scheduledAlertID) { clearTimeout(scheduledAlertID); statusMsg.textContent = "Timeout cancelled."; console.log("Timeout cancelled."); scheduledAlertID = null; } else { statusMsg.textContent = "No active timeout to cancel."; } });}*/实际应用:输入防抖 (Debouncing)
Section titled “实际应用:输入防抖 (Debouncing)”setTimeout 和 clearTimeout 常用于实现“防抖”(debouncing)。这是一种限制函数调用频率的技术,确保它只在一段时间不活动后才运行。例如,如果你有一个搜索输入框,在用户输入时进行 API 调用,你可能希望等待用户暂停输入后再发送请求。
// HTML: <input type="search" id="searchInput" placeholder="Search..." />/*let debounceTimer;function handleSearchInput(event) { clearTimeout(debounceTimer); const query = event.target.value; debounceTimer = setTimeout(() => { if (query.length > 0) { // 只在查询不为空时搜索 console.log(`Searching for: ${query}`); // fetchSearchResults(query); // 实际的 API 调用会放在这里 } else { console.log("Search query cleared."); } }, 500); // 等待 500ms 的不活动时间}
const searchInput = document.getElementById('searchInput');if (searchInput) { searchInput.addEventListener('input', handleSearchInput);}*/如前面时钟示例所示,setInterval 非常适合创建需要定期更新的功能,例如实时时钟、计数器或动画。