setInterval 함수와 타이머 이슈

MochaChoco·2023년 8월 17일
0
post-thumbnail

front-end 단에서 본인 인증 페이지를 작업 중인데, 본인 인증 요청 후 브라우저에 표시되는 인증 만료 시간과 서버에서 체크하는 인증 만료 시간이 일치하지 않는 문제점이 발생했다. 처음에는 서버 쪽 이슈인줄 알았는데, 테스트 결과 브라우저가 유휴 상태가 될때 두 시간이 어긋나는 것을 확인할 수 있었다.

창을 최소화 하거나 다른 탭으로 이동 후 일정 시간이 지나면 브라우저가 유휴 상태로 진입하는데, 이 때 JavaScriptsetInterval 함수가 느리게 돌아가는 것이 문제의 원인이었다.

setInterval 함수란?

어떠한 코드를 일정 시간 간격을 두고 반복적으로 실행할 때 사용하는 함수이다. setTimeout 함수와의 차이점은 한번 실행하느냐 여러번 반복적으로 실행하느냐의 차이이다.

setInterval 함수는 첫번째 인자로 동작을 실행할 함수를, 두번째 인자로 반복 주기(ms)를 입력받으며, 리턴 값으로 id값을 반환한다.

// 1000ms마다 "안녕하세요." 라는 문구를 출력한다.
setInterval(() => {
  console.log("안녕하세요.");
}, 1000);

반복을 종료하고 싶으면 clearInterval 함수에 setInterval 함수의 리턴 값(id)을 넣어서 호출하면 된다. 함수가 사용된 컴포넌트가 해제되거나 페이지 전환이 일어나는 등 더 이상 사용이 필요하지 않은 경우엔 메모리 누수 방지를 위해 반드시 clearInterval 함수를 호출하여야 한다.

let intervalId = 0;

// id값을 별도의 변수에 저장
intervalId = setInterval(() => {
  console.log("안녕하세요.");
}, 1000);

...

// 저장한 id값을 인자로 넣어서 함수를 호출한다.
clearInterval(intervalId);

해결 과정

해당 문제를 수정한 별도의 라이브러리가 존재하여 검토해봤지만, 브라우저가 유휴 상태일때도 강제로 타이머를 돌게하는 방식이라 메모리 누수같은 사이드 이펙트가 발생할 가능성이 높았다. 따라서 별도의 라이브러리를 사용하지 않고 현재 브라우저 탭이 focus in 될 때마다 인증 만료 시간이 갱신되게끔 작업하기로 했다.

let startTime = 0;		// 타이머 시작 시간
let seconds = 0;		// 브라우저에 표시할 시간
let intervalId = 0;		// setInterval 함수의 리턴 값을 저장할 변수

// 타이머 시작 함수
const startTimer = () => {
	startTime = Math.floor(Date.now() / 1000); 

  	// 현재 시간과 타이머 시작 시간을 비교한다.
  	seconds = Math.floor(Date.now() / 1000) - startTime.current;	
  
    intervalId = setInterval(() => {
      setTimer((prev) => prev + 1);
    }, 1000);
}

// 타이머 종료 함수
const stopTimer = () => {
 	clearInterval(intervalId);
    seconds = 0;
    intervalId = 0;
}

타이머 시작 함수와 종료 함수를 만들고, 아래 코드와 같이 브라우저가 focus in 될때 사용할 이벤트를 등록한다. 또한 페이지를 빠져나가는 시점에 등록된 이벤트를 해제해주어야 한다.

// 브라우저 focus in 이벤트 등록
window.addEventListener("focus", (e) => {
	clearInterval(intervalId);
	// 타이머 재시작
	startTimer();
});

...

// 페이지를 빠져나갈 때 등록된 이벤트를 제거한다.
window.removeEventListener("focus", null);

필요한 사람들을 위해 React로 구현한 별도의 샘플 코드를 아래에 남겨놓는다.

샘플코드

github 저장소 이동 (https://github.com/MochaChoco/set-interval)

참고 자료

자바스크립트의 setTimeout()과 setInterval() 함수
[JavaScript] setTimeout과 setInterval은 정확한 시간을 보장하지 않는다!
react로 setInterval을 사용할 때 겪을 수 있는 문제들

profile
길고 가늘게

0개의 댓글