Problem with timer in JavaScript especially when tab is inactive

99封情书 提交于 2021-02-10 09:55:00

问题


I have this timer in ReactJS that uses the computer's clock's time to run, which is supposedly more accurate than incrementing/decrementing the timer by 1 using setInterval with interval of 1 second. However, even when relying on the computer's clock, the timer's time drifts (by comparing it to this clock my app timer drifted 3 seconds in delay after 15 minutes running), and at some point it even stopped completely, while using other tabs in purpose.

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;

My questions is How can I create accurate timers in ReactJS/JavaScript that don't drift, and keep running accurately even when the tab in which they are running is inactive? How timers like this clock is created, and why it's accurate? Do I get better results if I get the timer from a backend?

来源:https://stackoverflow.com/questions/63954283/problem-with-timer-in-javascript-especially-when-tab-is-inactive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!