无需setInterval,如何高效持续检查变量值?增量游戏场景
高效检测进度条数值并触发重置的方案
最优方案:在进度更新逻辑中直接判断
既然你是主动控制进度条每秒增加1点,完全不需要额外的定时轮询——每次更新数值后立刻检查是否达到阈值,这是性能开销最低的方式。
let progress = 0; // 仅保留更新进度的定时器,每秒执行一次 const progressTimer = setInterval(() => { progress += 1; // 这里写更新进度条UI的逻辑(比如修改宽度、文字显示) updateProgressDisplay(progress); // 直接在更新后判断是否触发重置 if (progress === 10) { progress = 0; updateProgressDisplay(progress); // 这里添加进度重置后的逻辑(比如发放奖励、播放动画) } }, 1000); // 辅助函数:更新UI function updateProgressDisplay(value) { const bar = document.getElementById('progress-bar'); bar.style.width = `${value * 10}%`; bar.textContent = `${value}/10`; }
备选方案1:用Proxy监听变量变化
如果进度数值可能被其他代码修改(不只是每秒递增),可以用ES6的Proxy监听变量的修改操作,只有当数值真的变化时才执行检查,避免无意义轮询。
// 用代理包裹进度数值 const progressProxy = new Proxy({ value: 0 }, { set(target, prop, newValue) { target[prop] = newValue; // 数值变化时自动检查阈值 if (target.value === 10) { target.value = 0; updateProgressDisplay(target.value); // 执行重置后的逻辑 } else { updateProgressDisplay(target.value); } return true; } }); // 原来的进度更新定时器 setInterval(() => { progressProxy.value += 1; }, 1000); // 其他修改进度的地方也直接操作progressProxy.value即可
备选方案2:用MutationObserver监听DOM变化
如果你的进度条是通过DOM元素的属性(比如width)来体现的,可以用MutationObserver监听DOM变化,仅在进度条UI更新时判断阈值。
const progressBar = document.getElementById('progress-bar'); // 创建观察者实例 const observer = new MutationObserver((mutations) => { mutations.forEach(mut => { if (mut.attributeName === 'style') { // 解析当前进度(假设用百分比表示,10%对应1点) const currentProgress = parseInt(progressBar.style.width) / 10; if (currentProgress === 10) { progressBar.style.width = '0%'; progressBar.textContent = '0/10'; // 执行重置逻辑 } } }); }); // 启动监听,观察style属性变化 observer.observe(progressBar, { attributes: true }); // 进度更新定时器 let progress = 0; setInterval(() => { progress += 1; progressBar.style.width = `${progress * 10}%`; progressBar.textContent = `${progress}/10`; }, 1000);
总结
优先选择第一种方案,逻辑最直接,完全消除了额外轮询的性能消耗。只有当进度数值或DOM可能被外部代码修改时,再考虑用Proxy或MutationObserver方案——这两种方式都能做到“按需触发检查”,避免无效的定时器执行。
内容的提问来源于stack exchange,提问作者Jon Loftus
相关产品推荐
相关产品推荐

