JavaScript,ReactJS和在线计时器中的计时器精度

问题描述

我已经在原始JavaScript和ReactJS中实现了倒数计时器,并且将两个程序之间的计时器以及在线clock或手机中的倒数计时器进行比较时,我注意到该计时器与在线时钟相比,ReactJS中的计时器倾向于随时间漂移,而普通JavaScript中的计时器则保持恒定速度。

具体来说,我先在ReactJS应用程序中运行计时器,然后在JS应用程序中运行计时器,然后在在线时钟中运行计时器,最初我的React应用程序的计时器比JS中的计时器提前1秒,反过来比在线时钟快1秒。但是大约20分钟之后,我的React应用程序的计时器比我的JS应用程序的计时器晚1秒,而我的JS应用程序的计时器比在线时钟提前1秒。换句话说,我的React应用中的计时器在20分钟后延迟了2秒。

下面是我的代码

反应

import React,{ useState,useEffect } from 'react';
import './App.css';

function App() {
  const [sessionTime,setSessionTime] = useState(82.5);
  const [breakTime,setBreakTime] = useState(7.5);
  const [clockTime,setClockTime] = useState(82.5 * 60);
  const [current,setCurrent] = useState('session');
  const [isPlaying,setIsPlaying] = useState(false);

  useEffect(() => {
    document.title = convertTime(clockTime);
    if (isPlaying) {
      let startTime = new Date();
      const intervalId = setInterval(() => {
        if (clockTime === 0) {
          setCurrent(current === 'session' ? 'break' : 'session');
          setClockTime(
            current === 'session' ? breakTime * 60 : sessionTime * 60
          );
        } else {
          setClockTime(
            clockTime - (new Date().getTime() - startTime.getTime()) / 1000
          );
          // }
        }
      },200);
      return () => {
        clearInterval(intervalId);
      };
    }
  },[isPlaying,clockTime]);

  const handlePlayClick = () => {
    setIsPlaying(true);
  };

  const handlePauseClick = () => [setIsPlaying(false)];

  const convertTime = (count) => {
    let hours = Math.floor(count / 3600);
    let minutes = Math.floor(count / 60) - hours * 60;
    let seconds = parseFloat(count % 60).toFixed(0);
    if (hours < 10) hours = `0${hours}`;
    if (minutes < 10) minutes = `0${minutes}`;
    if (seconds < 10) seconds = `0${seconds}`;
    return `${hours}:${minutes}:${seconds}`;
  };
  return (
    <div className='App'>
      <span>{convertTime(clockTime)}</span>
      <span>{current}</span>
      {isPlaying ? (
        <button onClick={handlePauseClick}>Pause</button>
      ) : (
        <button onClick={handlePlayClick}>Play</button>
      )}
    </div>
  );
}

export default App;

香草JS

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <Meta charset="UTF-8" />
    <Meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>Count down timer</title>
  </head>
  <body>
    <span id="time-passed"></span>
    <button id="play">Play</button>
    <button id="pause">Pause</button>
  </body>
  <script src="app.js"></script>
</html>

app.js

const playBtn = document.querySelector('#play');
const pauseBtn = document.querySelector('#pause');

let counter = 82.5 * 60;
let timePassedElem = document.getElementById('time-passed');

const convertTime = (count) => {
  let hours = Math.floor(count / 3600);
  let minutes = Math.floor(count / 60) - hours * 60;
  let seconds = parseFloat(count % 60).toFixed(0);
  if (hours < 10) hours = `0${hours}`;
  if (minutes < 10) minutes = `0${minutes}`;
  if (seconds < 10) seconds = `0${seconds}`;
  return `${hours}:${minutes}:${seconds}`;
};
let intervalId;
playBtn.addEventListener('click',() => {
  let startTime = new Date();
  intervalId = setInterval(() => {
    document.title = convertTime(
      counter + Math.floor((startTime.getTime() - new Date().getTime()) / 1000)
    );
    timePassedElem.innerText = convertTime(
      counter + Math.floor((startTime.getTime() - new Date().getTime()) / 1000)
    );
  },200);
});

pauseBtn.addEventListener('click',() => {
  console.log('clicked');
  clearInterval(intervalId);
});

我的问题是,为什么我的ReactJS中的计时器会随时间漂移,而香草JS中却没有这种情况?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)