반응형

 

Hi there ~ 👋

 

요즘 열심히 블로그를 쓰고 있어요!! ㅎㅎ
블로그에 지난 3개월동안 소홀했었는데, 다시 힘을 내고 있습니다!! (아자아자)

 

안돼_일해
안돼 일해

 

오늘의 주제는 바로 타이머에요!

저희 회사에는 레거시가 되기 일보직전의 타이머 코드가 있었어요..🥺

 

회사의 다른 주니어 프론트엔드 개발자분들은 현재 진행중인 프로젝트가 있어서 수정하기에 바쁘신 것 같았어요!

그래서 제가 타이머의 구조와 로직을 개선하게 되었답니다..ㅎ

 

1. Event loop와 사이드 이펙트

첫 번째 문제였어요! 

 

버그-수정-전
버그 수정 전

 

// 레거시 코드가 될 타이머 코드..
const timeRef = useRef(0);

useEffect(() => {
    if (timeRef.current === 0 && startTime !== 0 && statusOfTime !== 'PAUSE')
      timeRef.current = Math.floor((Date.now() - startTime) / 1000);
    let interval = 0;

    switch (statusOfTime) {
      // 타이머가 돌아갈 때 - 문제가 되는 코드!
      case 'RUNNING':
        interval = window.setInterval(() => {
          timeRef.current++;
          if (checkCurrentTimeIsOverRange(timeRef.current)) {
            clearInterval(interval);
          }
        }, 1000);
        break;
      // 타이머가 일시정지했을 때
      case 'PAUSE':
        timeRef.current =
          pauseMatchTime !== 0 && timeRef.current === 0
            ? pauseMatchTime
            : timeRef.current;
        updatePauseTime(matchId, timeRef.current);
        clearInterval(interval);
        break;
      // 타이머가 대기 중일 때
      case 'READY':
        clearInterval(interval);
        timeRef.current = 0;
        break;
    }

    return () => clearInterval(interval);
  }, [
    isCountUp,
    statusOfTime,
    matchId,
    pauseMatchTime,
    setTime,
    startTime,
    stopWatchStartTime,
    checkCurrentTimeIsOverRange,
  ]);

 

기존 코드의 문제점은 setInterval로 매초마다 timeRef.current++ 하는 식으로 시간을 계산하는 것이었어요!

 

setInterval은 정확한 시간을 보장하지 않는다는 것으로 유명하죠.

 

JavaScript V8 엔진의 콜 스택에 다른 작업들이 쌓인다면 예상과 다른 결과가 발생할 수 있습니다.

즉, 1초마다 timeRef.current++가 실행되어야 하는데, 중간에 계속 다른 작업을 수행하게 되었을 때,
의존성 배열에 있는 값이 변하여 다른 작업이 먼저 수행되어 timeRef.current++가 밀릴 가능성이 존재합니다.

(실제로 위에 짤이 예시에요!)

 

이 부분에 대해서는 자세하게 다룬 바가 있습니다! -> 여기를 클릭

 

 

이벤트 루프의 개념을 적용하여 사이드 이펙트를 수정하여 버그는 수정했습니다.

 

버그-수정-후
버그 수정 후

 

 

이렇게 1단계 수정이 끝났습니다.

 

 

글이 너무 길어지는 것 같아서,

 

 

2편, 타이머의 시간을 보장해보자! 는 다음 시간에 찾아오겠습니다!

 

 

 


참고자료

 

https://ssocoit.tistory.com/249

 

[JavaScript] setTimeout과 setInterval은 정확한 시간을 보장하지 않는다!

이번에도 스톱워치를 만들다가.. 말로만 듣던 setTimeout과 setInterval의 시간보장문제를 직접 맞닥뜨리게 되었습니다. 말로만 듣던걸 간단한 프로그램을 만들면서 직접 겪으니까 참 오묘하네요 ㅎ

ssocoit.tistory.com

 

https://yeomyeom.tistory.com/94

 

[JS] Event loop

자바스크립트는 싱글 스레드 기반 언어이다. Non-blocking 방식의 비동기적인 동시성 언어이며 콜 스택, 이벤트 루프와 콜백 큐, 그리고 여러가지 다른 API들을 가지고 있다. 자바스크립트 엔진인 V8

yeomyeom.tistory.com

 

반응형

'TIL > 인턴' 카테고리의 다른 글

[TIL] 4학년 2학기 인턴 회고  (0) 2024.12.31
[TIL] setInterval, 시간보장 그리고 타이머 - 2편  (0) 2024.10.15
여름방학 인턴 회고  (16) 2024.10.03