FreeCodeCamp计时器项目测试失败:切换计时初始值错误求助
FreeCodeCamp计时器项目问题修复
问题描述
当前项目有两个测试用例未通过:
- 会话倒计时到
00:00后,休息倒计时实际从4分钟开始,预期应为break-length元素的当前值(如5分钟) - 休息倒计时到
00:00后,会话倒计时实际从0开始,预期应为session-length元素的当前值(如1分钟)
问题根源:当timeLeft归0后更新为新时长并递归调用startTimer时,新启动的定时器会先执行timeLeft--,再显示时间,导致初始显示的时长比预期少1分钟。
问题代码
function startTimer() { intervalId = setInterval(() => { timeLeft--; displayTimeLeft(); if (timeLeft === 0) { audio.play(); clearInterval(intervalId); if (onBreak) { onBreak = false; timeLeft = sessionLengthValue * 60; document.getElementById("status-label").textContent = "Session"; } else { onBreak = true; timeLeft = breakLengthValue * 60; document.getElementById("status-label").textContent = "Break"; } startTimer(); } }, 1000); }
解决方案
调整定时器内的执行顺序:先显示当前时间,再递减timeLeft,同时修改终止判断条件为timeLeft < 0,确保00:00显示完成后再切换计时阶段。
修正后的代码:
function startTimer() { intervalId = setInterval(() => { // 先显示当前时间,再递减 displayTimeLeft(); timeLeft--; // 当timeLeft变为-1时,说明已经显示过00:00,触发阶段切换 if (timeLeft < 0) { audio.play(); clearInterval(intervalId); if (onBreak) { onBreak = false; timeLeft = sessionLengthValue * 60; document.getElementById("status-label").textContent = "Session"; } else { onBreak = true; timeLeft = breakLengthValue * 60; document.getElementById("status-label").textContent = "Break"; } startTimer(); } }, 1000); }
补充说明
- 首次启动计时器前,建议先调用一次
displayTimeLeft(),确保初始时长显示正确 - 该逻辑避免了递归调用时直接递减新设置的
timeLeft,保证切换后的初始时长与预期一致
内容的提问来源于stack exchange,提问作者liamj009
相关产品推荐
相关产品推荐

