clearTimeout(), clearInterval()

이서현·2023년 5월 29일
0

JavaScript

목록 보기
3/4

setTimeout(), setInterval() 취소하기

얘네 둘 다 반환값으로 타이머 식별자(숫자)를 준다
이 타이머 식별자로 스케줄링 취소하기 가능
✨ 동일한 식별자를 사용하는 게 아주 중요
✨ 타이머마다 식별자가 달라져요~~

let timerId = setTimeout(() => alert("아무런 일도 일어나지 않습니다."), 1000);
alert(timerId); // 타이머 식별자

clearTimeout(timerId);
alert(timerId); // 위 타이머 식별자와 동일함 (취소 후에도 식별자의 값은 null이 되지 않습니다.)

setTimeout 함수에 인수로 넣은 함수가 실행되기 전에 clearTimeout을 호출해야 함

취소했다가 다시 실행하기

let intervalId = setInterval(changeComputerHand, 50); // 식별자를 변수에 담고
const clickButton = () => {
  clearInterval(intervalId); // 위에서 저장한 식별자를 이용해 취소
  setTimeout(() => {
    // 타이머마다 식별자가 달라지기 때문에 새로운 타이머의 식별자를 다시 할당
    intervalId = setInterval(changeComputerHand, 50);
  }, 1000);
};

$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$paper.addEventListener("click", clickButton);

문제점


버튼을 3번 연속으로 누르면 한번 멈췄다가 정해진 것보다 빠르게 이미지가 빠르게 움직이고
다시 버튼을 클릭해도 이미지가 멈추지 않는다

클릭마다 타이머 식별자도 바뀌고 clearInterval도 식별자마다 3번 취소될거라 예상했는디 아니네 ㅎ

위 콘솔을 보면 다시 할당된 인터벌아이디는 총 3개인데 마지막 10만 저장이 됐다
그래서 나중에 버튼을 클릭했을 때 clearInterval에 사용되는 아이디는 10인 것!
취소하려는 타이머는 식별자가 꼭 동일해야 취소가 가능하기에 저장되지 않은 식별자는 지나간 버스~~
취소되지 않은 8이랑 9가 계속 돌아가서 이미지가 멈추지 않는 것

해결방법

1. 내가 예상한대로 clearInterval 해주기

let intervalId = setInterval(changeComputerHand, 50);
const clickButton = () => {
  clearInterval(intervalId);
  setTimeout(() => {
    clearInterval(intervalId); // 비동기니까 위 clear랑 안 겹침
    intervalId = setInterval(changeComputerHand, 50);
  }, 1000);
};

2. removeEventListener()

뭔가 멋없어 보여

let intervalId = setInterval(changeComputerHand, 50);
const clickButton = () => {
  clearInterval(intervalId);
  // 취소하기
  $rock.removeEventListener("click", clickButton);
  $scissors.removeEventListener("click", clickButton);
  $paper.removeEventListener("click", clickButton);
  
  setTimeout(() => {
    intervalId = setInterval(changeComputerHand, 50);
    // 취소한 거 다시 이벤트리스너 붙여주기
    $rock.addEventListener("click", clickButton);
    $scissors.addEventListener("click", clickButton);
    $paper.addEventListener("click", clickButton);
  }, 1000);
};

$rock.addEventListener("click", clickButton);
$scissors.addEventListener("click", clickButton);
$paper.addEventListener("click", clickButton);

3. 변수 만들어서 제어

let CLICKABLE = true;
let intervalId = setInterval(changeComputerHand, 50);
const clickButton = () => {
  if (CLICKABLE) {
    clearInterval(intervalId);
    CLICKABLE = false;
    setTimeout(() => {
      CLICKABLE = true;
      intervalId = setInterval(changeComputerHand, 50);
    }, 1000);
  }
};

4. disabled

이것도 멋없네

const clickButton = () => {
  clearInterval(intervalId);
  $rock.disabled = true;
  $scissors.disabled = true;
  $paper.disabled = true;
  setTimeout(() => {
    intervalId = setInterval(changeComputerHand, 50);
    $rock.disabled = false;
    $scissors.disabled = false;
    $paper.disabled = false;
  }, 1000);
};

궁금했었던 점

setInterval(changeComputerHand, 50);

이건 함수 호출
함수 호출은 뭐다? 반환값이 있다

let intervalId = setInterval(changeComputerHand, 50);

근데 왜 변수에 할당만 했는데 실행이 되는 걸까?
함수 호출을 변수에 할당 === 반환값을 변수에 할당

profile
🌿💻💪🧠👍✨🎉

0개의 댓글