如何让SuperCounter类实例各自独立停止计数?
SuperCounter类实例计数独立控制修复方案
核心问题诊断
- 全局定时器共享:所有计数器实例依赖同一个全局
ignition定时器,任意实例触发clearInterval(ignition)会直接终止所有计数。 - 停止逻辑侵入全局:类的
add方法直接操作全局定时器,破坏了实例独立性,导致单个实例到达上限时所有计数停摆。
修复代码
修改后的JavaScript代码
document.addEventListener("DOMContentLoaded", (event) => { console.log("DOM fully loaded and parsed"); }); class SuperCounter { constructor(cumul, limit) { this.cumul = cumul; this.limit = limit; this.isStopped = false; // 实例独立状态:标记是否已达上限 } add() { if (this.isStopped) { return { result: this.cumul - 1 }; // 返回最后一个有效计数值 } const currentValue = this.cumul; // 到达上限时标记停止状态,不操作全局定时器 if (currentValue === this.limit) { console.warn(`Counter reached limit: ${this.limit}`); this.isStopped = true; } else { this.cumul++; } return { result: currentValue }; } // 供外部查询实例是否已停止 hasStopped() { return this.isStopped; } } const firstCounter = new SuperCounter(1, 50); const secondCounter = new SuperCounter(1, 150); const ignition = setInterval(displayCounter, 100); function displayCounter() { // 仅更新未停止的计数器 if (!firstCounter.hasStopped()) { document.querySelector("#chrono1").innerHTML = /*html*/ `<h2>Chrono #1 : ${firstCounter.add().result}</h2>`; } if (!secondCounter.hasStopped()) { document.querySelector("#chrono2").innerHTML = /*html*/ `<h2>Chrono #2 : ${secondCounter.add().result}</h2>`; } // 所有计数器都停止时,再清除全局定时器 if (firstCounter.hasStopped() && secondCounter.hasStopped()) { clearInterval(ignition); console.log("All counters completed."); } }
HTML代码
<h3 id="chrono1"></h3> <h3 id="chrono2"></h3>
修复说明
- 实例状态独立:每个
SuperCounter实例通过isStopped属性管理自身停止状态,不再依赖全局变量,实现计数上限独立生效。 - 全局定时器统一管理:将定时器清除逻辑从类内部移到外部回调,仅当所有实例都停止时才终止定时器,避免单个实例影响全局。
- 计数逻辑修正:调整
add方法返回值逻辑,确保到达上限时返回最后一个有效数值,且不会重复触发停止警告。
内容的提问来源于stack exchange,提问作者Christophe Lami
相关产品推荐
相关产品推荐

