주의! : 이번 글은 제목부터 어그로성이 다분합니다🤦♂️
이 글을 쓰게 된 이유는, 주기적으로 어떤 작업을 해야하는 상황에서 setInterval이 좋은 선택인지에 대해 얘기해보기위해서입니다.
clearInterval()
을 사용하여 중지합니다.clearTimeout()
을 사용하여 작업을 중지합니다.문제가 없어보이지만, setInterval
에선 맹점이 하나 있습니다.
위 문서의
Delay restrictions
에서도 언급하고 있듯이,setInterval
은 다른 interval이 running 되고 있는 동안에도 또 다른setInterval
의 callback이 호출 될 수 있습니다.
어떤 A라는 작업을 setInterval
을 이용하여 반복하고 싶은데, 이 A라는 작업이 지정해놓은 interval보다 오래 걸리면 선행 작업이 끝나지도 않은채 또 다른 A작업을 시작하게 된다는 것입니다.
이렇게 되면 생각지도 못한 side effect가 일어날 수 있고
개발자는 A가 순차적으로 끝난 뒤 반복 되는 줄 알았는데..
그냥 끝나지도 않은 채 반복해버리니 이게 무슨 상황인가 당황하게 되버릴겁니다.
setTimeout
을 재귀적으로 호출하여 사용자 정의 setInterval
을 선언하면 됩니다.
setTimeout
은 일단 지정해놓은 시간만큼 대기 후 작업을 진행하기 때문에, 재귀적으로 호출하게 되면 setInterval
과 달리 선행 작업이 끝나고 interval만큼 기다린 뒤에 실행되게 됩니다.
아래와 같은 패턴을 사용하여 mySetInterval
이라는 함수를 정의하면 됩니다.
const mySetInterval = () => {
setTimeout(() => {
A();
mySetInterval();
}, delay);
};
이렇게 되면, 아래와 같은 순서로 실행이 됩니다.
delay 만큼 대기 -> A 작업 실행 및 종료 -> mySetInterval이 재귀로 실행 -> delay 만큼 대기 -> ... 반복
이렇게 setTimeout
을 재귀적으로 구현함으로써, setInterval
이 가지고 있는 문제를 해결 할 수 있었습니다.
사실 이 문제는 직접 어떤 것을 개발하다가 직접 겪게 되어서 정리할김에 적어본 글입니다.
글의 제목이 어그로성이 짙어서 조금 그럴 수도 있지만, 많은 분들께 도움이 되었으면 좋겠습니다 😄
아 그리고, 만약 A라는 작업을 선행 작업이 끝나던 말던 상관없이 interval 마다 실행하고 싶다면 setInterval
을 사용해야겠죠?