You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 00:25:19