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 |