如何从另一个函数中清除setInterval定时器
解决方案
核心原因
setInterval 执行后会返回一个唯一的数字ID,只有拿到这个ID才能通过 clearInterval 终止对应的定时任务。你当前的代码没有存储这个ID,也没有在重置函数中执行清除逻辑,所以定时器会一直运行。
具体修改步骤
- 在两个函数的外层作用域声明变量,用于存储定时器ID
- 启动定时器时将返回的ID赋值给外层变量,每次启动前先清除已有定时器,避免多次调用启动函数生成多组重复定时任务
- 重置函数中新增清除定时器的逻辑,清除后重置ID变量
修改后完整代码
// 外层作用域存储定时器ID let timelapsIntervalId = null; function startTimelapsFunction() { // 启动前先清除已有的定时器,避免重复运行 if (timelapsIntervalId) { clearInterval(timelapsIntervalId); } if (!localStorage.getItem('startTime')) { localStorage.setItem('startTime', Date.now()); } const startTime = parseInt(localStorage.getItem('startTime'), 10); const writeTime = () => { console.log('startTime', startTime) const currentTime = Date.now(); console.log('currentTime', currentTime) const secondsDiff = Math.floor((currentTime - startTime) / 1000); console.log('secondsDiff', secondsDiff) document.body.innerText = secondsDiff; localStorage.setItem('myCat', secondsDiff); }; // 存储定时器ID timelapsIntervalId = setInterval(writeTime, 1000); writeTime(); } function resetTimelapsFunction() { // 清除运行中的定时器 if (timelapsIntervalId) { clearInterval(timelapsIntervalId); timelapsIntervalId = null; } localStorage.removeItem("myCat"); localStorage.removeItem("startTime"); }
可选优化方案(避免污染全局作用域)
如果不想额外声明全局变量,可以用闭包封装逻辑,把定时器ID隐藏在私有作用域中:
const timelapsController = (() => { let intervalId = null; return { start: () => { if (intervalId) clearInterval(intervalId); if (!localStorage.getItem('startTime')) { localStorage.setItem('startTime', Date.now()); } const startTime = parseInt(localStorage.getItem('startTime'), 10); const writeTime = () => { const currentTime = Date.now(); const secondsDiff = Math.floor((currentTime - startTime) / 1000); document.body.innerText = secondsDiff; localStorage.setItem('myCat', secondsDiff); }; intervalId = setInterval(writeTime, 1000); writeTime(); }, reset: () => { if (intervalId) { clearInterval(intervalId); intervalId = null; } localStorage.removeItem("myCat"); localStorage.removeItem("startTime"); } } })(); // 调用方式 // timelapsController.start() // timelapsController.reset()
内容的提问来源于stack exchange,提问作者ProgrammerGirl
相关产品推荐
相关产品推荐

