JavaScript函数重复调用后setInterval计时加速问题求助
问题原因与解决方案
这问题太典型了——你每次调用newCall()的时候,都会新建两个setInterval定时器,但从来没有清除过之前创建的定时器!
举个实际运行的场景:
- 第一次启动
newCall(),会生成一个每秒执行的timer定时器(负责给seconds加1),同时生成一个随机时间后触发newCall的定时器。 - 等随机时间到了,第二次调用
newCall()时,又会新建一组timer和newCall定时器,但第一次创建的两个定时器还在后台悄悄运行呢! - 这会儿就有两个
timer同时每秒执行seconds++,自然计时速度就变成两倍了;调用次数越多,同时跑的timer越多,计时速度就越来越快。
修复方案:保存定时器ID,每次调用前清除旧定时器
我们需要把setInterval返回的定时器ID保存下来,这样每次调用newCall()时,先把之前的定时器全部清除,再创建新的,避免多个定时器叠加运行。
修改后的完整代码如下:
// 全局变量保存定时器ID,方便后续清除 let timerInterval; let newCallInterval; let seconds = 0; function newCall() { // 清除之前的定时器,防止叠加 if (timerInterval) clearInterval(timerInterval); if (newCallInterval) clearInterval(newCallInterval); const min = 3000; const max = 20000; const rand = Math.floor(Math.random() * (max - min + 1) + min); console.log("TEST - random time: " + rand); seconds = 0; // 重新创建定时器并保存ID timerInterval = setInterval(timer, 1000); newCallInterval = setInterval(newCall, rand); } function timer() { seconds++; console.log("test " + seconds); } // 初始调用启动流程 newCall();
额外优化提示
如果你的需求是newCall只在随机时间后触发一次(而不是循环触发),其实可以用setTimeout代替setInterval,这样逻辑会更简洁,还能避免循环定时器的清除问题:
let timerInterval; let seconds = 0; function newCall() { if (timerInterval) clearInterval(timerInterval); const min = 3000; const max = 20000; const rand = Math.floor(Math.random() * (max - min + 1) + min); console.log("TEST - random time: " + rand); seconds = 0; timerInterval = setInterval(timer, 1000); // 用setTimeout只触发一次newCall setTimeout(newCall, rand); } function timer() { seconds++; console.log("test " + seconds); } newCall();
内容的提问来源于stack exchange,提问作者Natixco
相关产品推荐
相关产品推荐

