请用 JavaScript 给出一个倒计时器的实现方案,要求它允许外部设置目标时长,并在计时归零时触发一个回调事件。
考察说明
考察候选人使用 JavaScript 实现定时逻辑、处理时间计算与边界条件的能力。
回答思路
- 【回答框架 1】基于 Date.now() 计算剩余时间,而非简单递减计数器,以避免定时器因系统休眠或延迟累积导致偏差。
- 【回答框架 2】使用 setTimeout 递归调用或 setInterval 循环,并在回调中重新计算剩余时间,到 0 时调用 onEnd 回调并清理定时器。
- 【回答框架 3】将目标时长以毫秒为单位传递,内部存储 endTime = startTime + duration,每次 tick 计算 remaining = Math.max(0, endTime - Date.now())。
- 【回答框架 4】提供暂停、恢复、重置等控制方法时,需要记录暂停时刻的剩余时间,以便恢复后准确计算。
- 【回答框架 5】注意在页面隐藏或后台时浏览器可能节流定时器,可使用 visibilitychange 事件或 Web Worker 保精度。
- 【关键点 1】用 endTime 减去 Date.now() 得到剩余时间,不依赖计数累加。
- 【关键点 2】倒计时结束需明确清除定时器,避免内存泄漏。
- 【关键点 3】对暂停恢复状态管理需记录暂停时剩余时间。
- 【易错点 1】仅靠 setInterval 计数易受节流影响导致时间不准。
- 【易错点 2】倒计时结束回调可能重复触发,需通过剩余时间判断并清理。
- 【易错点 3】若直接用递减计数而不考虑系统休眠,恢复后显示时间会与实际时间不符。