본문 바로가기

Front-End/Javascript

[TIL] setInterval, 시간보장 그리고 타이머 - 2편

반응형

 

지난 시간까지 setInterval이 왜 시간 보장을 해주지 않는지, 

event loop에 대한 개념과 이로 인해 발생한 사이드 이펙트까지 알아봤어요!

 

setInterval-시간보장
🔥

 

 

이번 시간에는 timeRef(useRef)에 매초 +1 씩 더하는 로직을 어떻게 수정했는지, 

시간 계산을 어떻게 하여 시간 보장이 되었는지 공유해볼게요! ☺️

 


1. Date.now()를 활용한 시간보장

JavaScript를 다뤄보신 분들이라면 모두 한 번쯤은 보신 Date.now()를 활용했어요!

 

// MEMO :: 타이머 시작
// 참고만 해주세요!
  const start = useCallback(async () => {
    if (intervalRef.current !== null) {
      return;
    }

    if (isCountUp) {
      intervalRef.current = setInterval(() => {
        setCount(
          stopWatchStartTime + Math.floor((Date.now() - standardTime) / 1000),
        );
      }, 100);
    } else {
      intervalRef.current = setInterval(() => {
        setCount(setTime - Math.floor((Date.now() - standardTime) / 1000));
      }, 100);
    }
  }, [stopWatchStartTime, isCountUp, standardTime]);

 

setInterval은 그대로 사용해도 Date.now()를 이용해서 현재 시간을 보장할 수 있도록 작성해보았어요!!

Date.now()에서 타이머를 시작했던 시간의 차이를 구하고, 1000으로 나눠 초단위로 변경했습니다.

Math.floor()을 적용하여 뒤의 소수점은 버렸습니다..!

 

예) 

시간보정-계산법
시간보장을 위한 예시 1

 

시간보장을 위한 계산 예시 2

 

위의 실제로 예시를 보시면

startTime을 할당하고, currentTime까지 할당하는데 12초가 걸렸다는 사실을 알 수 있네요!!

 

위와 같은 방식으로 1초마다 얼마의 시간이 흘렀는지 계산할 수 있었어요!!

 

setInterval-시간보장-해결방법
할 수 있다!

 


 

2. 일시정지했을 때는 어떻게 계산할까?

타이머를 멈췄을 때는 어떻게 계산했을까요?

// standardTime을 멈춘 시간을 기점으로 업데이트해줍니다.
// 일시정지를 유지한 시간까지 고려해서 재시작하는 시간을 계산해야 했습니다.
const amountOfPausedTime = Date.now() - timeData.pauseTime;
timeData.standardTime = timeData.standardTime + amountOfPausedTime;

// PAUSE 상태일 때, 실행하는 코드
// pauseTime은 정지했을 때의 Date.now()값을 가지고 있습니다.
// 이를 계산하여 pausedTime(pauseTime X)으로 할당합니다.
const pausedTime = Math.floor((pauseTime - standardTime) / 1000);
pause(pausedTime);

// pause 함수
// 정지된 시간을 setCount로 설정합니다.
const pause = useCallback(
    async (pausedTime: number) => {
      clearInterval(intervalRef.current ?? undefined);
      intervalRef.current = null;

      if (pausedTime === 0) return;

      if (isCountUp) {
        setCount(stopWatchStartTime + pausedTime);
      } else {
        setCount(setTime - pausedTime);
      }
    },
    [isCountUp, stopWatchStartTime, setTime],
  );

 

위의 코드를 보시면,

일시정지를 했을 때는 일시정지를 시작한 시간과 일시정지를 지속한 시간을 알아야 합니다.

 

이를 바탕으로 계산을 하여 카운트업/다운에 따라 계산해주면 됩니다!!

 


 

 

오늘은 텍스트로만 전달하기에는 어려울 수도 있는 내용을 작성해보았는데요!

궁금하신 점이 있으시면 댓글로 남겨주세요!

 

바로 답변하겠습니다~ 🤗

반응형