[JS] setTimeout과 setInterval 차이

이의섭·2022년 1월 2일
0
post-thumbnail

setTimeoutsetInterval는 기본적으로 무언가를 일정 간격을 두고 실행하도록 만들어주는 스케줄링 메서드 입니다.

두 녀석 다 반환값으로 Timer Identifier를 반환해서 clearTimeout(timerId), clearInterval(timerId)의 매개변수로 걸어놓았던 스케줄링을 취소할 수 있습니다.

둘의 차이점

첫번째 차이점

저는 둘의 가장 큰 차이점은 한 번만 하냐 무한번 반복하냐 라고 알고 있었습니다.

하지만 setTimeout으로도 setInterval과 같은 기능을 수행할 수 있다고 합니다.

바로 중첩 setTimeout방식을 사용하면 된다고 합니다.

let timerId = setTimeout(function tick() {
  alert("째깍");
  timerId = setTimeout(tick, 2000); // ----(1)-----
}, 2000);

(1)로 표시한 줄은 첫 스케줄링이 실행을 종료하면 다음 호출을 스케줄링 하는 방식으로 매번 자기 자신을 호출함으로써 무한번 수행시킬 수 있습니다.

이렇게 중첩 setTimeout을 이용하는 방법은 setInterval을 사용하는 방법보다 다른 복잡한 상황들을 유연하게 처리할 수 있다고 합니다.

예시

5초 간격으로 서버에 요청을 보내 데이터를 얻는다고 가정해 봅시다. 서버가 과부하 상태라면 요청 간격을 10초, 20초, 40초 등으로 증가시켜주는게 좋을 겁니다.

let delay = 5000;

let timer = setTimeout(function request() {
  ...요청 보내기...
  
  if(서버 과부하로 인한 요청 실패) {
    // 요청 간격을 늘립니다.
    delay *= 2;
  }
  
  timerId = setTimeout(request, delay);
}, delay);

이처럼 동적으로 delay를 변화시키면서 유연하게 처리할 수 있습니다.

두번째 차이점

중첩 setTimeout은 시간 지연 간격을 보장하지만 setInterval은 시간 지연을 보장하지 않습니다.

예시

100ms마다 스케줄링한 함수를 호출한다고 가정해봅시다.

그 결과는 그림과 같습니다. setInterval로 호출한 함수는 지연 시간속에 함수를 실행하는 데 소모되는 시간도 포함시킨다고 합니다.

하지만 함수를 실행하는데 소모되는 시간이 명시한 지연 시간보다 길 땐 어떤 일이 발생할까요?

이런 경우는 에러가 발생하진 않고 엔진이 함수의 실행이 종료될 때까지 기다리다 종료가 되면 스케줄러를 확인하고 지연시간이 지났으면 바로 다음 호출을 시작한다고 합니다.

반면 중첩 setTimeout은 함수 실행 시간을 포함하지 않고 함수의 실행이 끝나고 난 뒤 다음 함수 호출에 대한 계획이 세워지기 때문에 지연시간이 보장된다고 합니다.

가비지 컬렉션

setTimeoutsetInterval의 콜백함수로 넘기면, 함수에 대한 내부 참조가 새롭게 만들어지고 이 참조 정보는 스케줄러에 저장됩니다. 따라서 해당 함수를 참조하는 것이 없어도 가바지 컬렉션의 대상이 되지 않습니다. 즉 스케줄러가 함수를 호출할 때까지 함수는 메모리에 유지된다고 합니다.

setInterval의 경우는 clearInterval이 호출되기 전까진 함수에 대한 참조가 메모리에 유지되기 때문에 가령 외부 렉시컬 환경을 참조하는 함수가 있다고 하면 이 함수가 존재하는 이상 외부 렉시컬 환경 또한 가비지 컬렉션의 대상이 되지 않아 실제 함수가 차지했어야 하는 공간보다 더 많은 메모리 공간이 사용된다고 합니다.

따라서 스케줄링할 필요가 없어진 함수는 아무리 작더라도 취소하도록 합시다.

profile
사용자 중심 생각하는 프론트엔드 개발자가 되고 싶은..

0개의 댓글