typescript setInterval 문제

강정우·2024년 7월 16일
0

TypeScript

목록 보기
23/23
post-thumbnail

setInterval 을 한 컴포넌트에서 선언하고 다른 컴포넌트에서 멈추게 할 때, 안 먹는 경우가 있다.

예를 들어 어떠한 문제가 말생하여 해당 문제인 부분을 사용자가 어떠한 행동을 할때 까지 계속 깜빡이게 하고, 행동이 완료되면
해당 Interval 을 null 로 하여 멈추게 할 때 멈추지 않고 setInterval 이 중복되는 문제가 발생하는데 이는 interval 을 설정한 객체를 같은 객체를 보지 못 하고 생겨나는 문제이다. 예를들어

const isOrdered = ref<any>(null);

isOrdered.value = setInterval(()=>mapStore.blinkIcon(+data.sensorInfo.sensorSeq), 2000)

위 코드에서 isOrdered 의 값에 계속 다른 Interval 이 할당되어 setInterval 이 계~속 중복되는 문제이다.

그리고 사용자가 어떠한 동작을 하면 아래 함수가 실행되며 깜빡임이 멈추는 코드이다.

const postOrderRequest = () => {
    clearInterval(isOrdered.value)
}

원인은 isOrdered.value에 setInterval의 반환값이 제대로 저장되지 않아서 발생하는 것 이다.
setInterval의 반환값은 number 타입의 ID인데, 이를 clearInterval에 전달하여 해당 인터벌을 정지할 수 있다.

그래서 반드시 체크해줘야할 부분이 2개 있다.
1. isOrdered가 올바른 setInterval ID를 받는지 확인해야 함.
2. clearInterval이 올바르게 호출되는지 확인해야 합니다.

// isOrdered 변수를 ref로 선언합니다.
const isOrdered = ref<number | null>(null);

let currentStyle = true;
const blinkIcon = (sensorSeq: number) => {
    const targetFeature = featureObj.value!.getSource().getFeatures().find((el: any) => "sensor_" + sensorSeq === el.values_.id);
    if (targetFeature) {
        if (currentStyle) {
            targetFeature.setStyle(newStyle);
        } else {
            targetFeature.setStyle(oldStyle);
        }
    }
    currentStyle = !currentStyle;
};

// 특정 상황일 때 setInterval 설정
const startBlinking = () => {
    if (isOrdered.value === null) {
        isOrdered.value = setInterval(() => mapStore.blinkIcon(+data.sensorInfo.sensorSeq), 2000);
    }
};

// 사용자가 버튼을 누르면 setInterval 정지
const postOrderRequest = () => {
    if (isOrdered.value !== null) {
        clearInterval(isOrdered.value);
        isOrdered.value = null;
    }
};
  1. isOrdered 변수는 number | null 타입으로 선언.
    이는 setInterval ID가 number 타입이므로 정확한 타입을 지정하기 위함.
  2. startBlinking 함수는 setInterval을 시작할 때 isOrdered.value가 null인지 확인.
    이는 중복된 인터벌 설정을 방지하기 위함임.
  3. postOrderRequest 함수는 clearInterval을 호출한 후 isOrdered.value를 null로 재설정.
    이는 인터벌이 제대로 정지되고, 다음 인터벌 설정을 위해 상태를 초기화하기 위함.

문제의 원인은 주로 두 가지였다.

  1. isOrdered.value의 타입 및 초기화 문제:

원래 isOrdered는 ref<any>(null) 로 선언되어 있었지만, setInterval이 반환하는 값은 number이다. 타입이 일치하지 않으면 의도한 대로 작동하지 않을 수 있다. isOrdered를 ref<number | null>(null) 로 선언함으로써 타입을 명확히 하여 문제를 해결

  1. setInterval ID 관리 문제:

setInterval이 실행될 때마다 반환된 ID를 isOrdered.value에 저장해야 하는데, 이를 명확히 하지 않으면 clearInterval에서 올바른 ID를 전달하지 못해 인터벌이 제대로 정지되지 않을 수 있다.
또한, clearInterval 후에 isOrdered.value를 null로 재설정하지 않으면 인터벌이 중복 실행될 수 있다. 이를 통해 새로운 인터벌이 설정되기 전에 이전 인터벌이 정지되도록 보장했다.

profile
智(지)! 德(덕)! 體(체)!

0개의 댓글