首页 > 解决方案 > 我怎样才能弄清楚为什么这个计时器功能不起作用

问题描述

我正在尝试创建一个“番茄钟”计时器,它接受用户输入并根据某人想要使用它的时间创建一个计时器(除了为自己学习和使用它之外没有其他原因)。

我发现我的for循环没有像我期望的那样运行,当你查看计时器本身时,它每秒都在倒计时,但是计时器本身实际上每计数一秒就会减少 6 秒。

一旦达到零,我似乎也无法让计时器继续前进到下一位。

我最初确实在函数中有中断,以便它会从当前时间移动到休息时间,但这似乎没有奏效。

就 6 秒问题而言,我什至不知道从哪里开始。

// set up a counter for how many times you want to set the pomodoro for - users will input how many cycles they want the program to go through.

const pomodoroQuestion = prompt("How many times would you like to use the pomodoro (1 Pomodoro = 3x 25 minute working burst, 2x 5 minute breaks and 1x 15 minute break)");
const pomodoroLength = parseInt(pomodoroQuestion);

for (let i = 0; i < pomodoroLength; i++) {

  function startTimer() {
    const currentTime = document.getElementById('pomodoroClock').innerHTML;
    const timeArray = currentTime.split(/[:]+/);
    let minutes = timeArray[0];
    let seconds = secondsTimer((timeArray[1] - 1));

    if (seconds === 59) {
      minutes = minutes - 1;
    }

    if (minutes < 0) {
      alert("Time's up");
    }

    document.getElementById('pomodoroClock').innerHTML = `${minutes}:${seconds}`;
    setTimeout(startTimer, 1000); // Make the function countdown each second
  }

  // cycle through the seconds
  function secondsTimer(sec) {
    if (sec < 10 && sec >= 0) {
      sec = `${0}${sec}`;
    }
    if (sec < 0) {
      sec = 59;
    }
    return sec;
  }

  // the following loop will be what starts the actual pomodoro cycle.
  for (let x = 0; x < 3; x++) {
    // function starting a countdown timer for 25 minutes
    document.getElementById('pomodoroClock').innerHTML = `${25}:${00}`;
    startTimer();

    if (x < 2) {
      // this is where you're going to perform the function that'll allow for a 5 minute break
      document.getElementById('pomodoroClock').innerHTML = `${05}:${00}`;
      startTimer();

    } else {
      // this is where you're going to perform the function that'll allow for a 15 minute break
      document.getElementById('pomodoroClock').innerHTML = `${15}:${00}`;
      startTimer();
    }
  }

} // end pomodoroLength loop
<div id="pomodoroClock" class="timer"></div>
<script src="script/script.js"></script>

我在哪里错了这个?我觉得我只是缺少对此类项目的一些关键理解,因此创建了一些小的实践项目来改进。

标签: javascriptfunctionloops

解决方案


我认为改变你的方法是值得的。如果你有一个独立的countdown()函数在给定的目标元素中显示分钟和秒,并在完成时通知你怎么办?

用承诺很容易做到这一点。您创建了一个返回 a 的函数new Promise,并且您resolve()在时间为零时做出承诺:

function countdown(minutes, seconds, targetElement) {
  return new Promise(resolve => {
    const tick = setInterval(function () {
      // count down, display current time in targetElement
      if (/* time's up */) {
        // stop interval, call resolve()
      }
    }, 1000);
  });
}

async由于这个函数返回一个承诺,用/链接多个这些函数变得很简单await

async function countdownSequence(...timers) {
  for (let t of timers) {
    await countdown(0, t, document.getElementById('target'));
  }
  alert('done!');
}

countdownSequence(5, 10, 5);  // counts 5, 10, and 5 seconds, and then alerts 'done!'

完全实施,有一些额外的东西。请注意,为了示例,我使用的是 ,而不是25, 5, 25, 5, 25, 15每轮使用您的序列5, 2, 5, 2, 5, 3,并且我使用的是函数的seconds插槽。countdown

function countdown(minutes, seconds, targetElement) {
  const pad = num => (num < 10 ? '0' : '') + num;
  const display = () => targetElement.textContent = pad(minutes) + ':' + pad(seconds);
  return new Promise(resolve => {
    const tick = setInterval(function () {
      seconds--;
      if (seconds < 0) {
        minutes--;
        seconds = 59;
      }
      if (minutes < 0) {
        clearInterval(tick);
        resolve();
      }
      display();
    }, 1000);
    display();
  });
}

async function pomodoro(numCycles, targetElement) {
  targetElement.classList.add('active');
  for (let i = 0; i < numCycles; i++) {
    targetElement.classList.remove('work');
    for (let minutes of [5, 2, 5, 2, 5, 3]) {
      targetElement.classList.toggle('work');
      await countdown(0, minutes, targetElement);
    }
  }
  targetElement.classList.remove('active');
}

async function start() {
  const cycles = parseInt(prompt("How many times would you like to use the pomodoro (1 Pomodoro = 3x 25 minute working burst, 2x 5 minute breaks and 1x 15 minute break)"), 10);
  if (cycles > 0) {
    await pomodoro(cycles, document.getElementById('pomodoroClock'));
    alert("Finished!");
  }
}

start();
#pomodoroClock {
  display: none;
}
#pomodoroClock.active {
  display: block;
  color: blue;
}
#pomodoroClock.work {
  color: green;
}
#pomodoroClock::after {
  padding-left: 5px;
  content: '(pause)';
}
#pomodoroClock.work::after {
  padding-left: 5px;
  content: '(work time)';
}
<div id="pomodoroClock"></div>


推荐阅读