setTimeOut과 setInterval (가위바위보 예제)

frenchkebab·2021년 9월 19일
0

javascript 지식

목록 보기
13/36

ZeroCho님의 렛츠기릿 자바스크립트 교재를 공부하며 작성한 글입니다.

setTimeOut과 setInterval


setTimeOut

function hello() {
  console.log('hello');
  setTimeout(hello, 1000);
}
setTimeout(hello, 1000);

setTimeOut은 hello()내의 console.log의 실행이 끝난 후 실행되므로, 이전의 코드가 늦게 끝나면 1000ms가 맞춰지지 않을 수도 있다
(1초 이상이 될 수도 있다)


setInterval

setInterval(() => {
  console.log('hello');
}, 1000);

setInterval의 경우 최대한 1000ms을 맞추고자 노력한다.


clearInterval

let 아이디 = setInterval(함수, ms);
clearInterval(아이디); // setInterval의 반환값을 인자로 받는다

예시

let intervalId = setInterval(changeComputerHand, 50);

const clickButton = () => {
  clearInterval(intervalId); // 여기서 같은 ID를 여러 번 제거하게 됨
  setTimeout(() => {
    intervalId = setInterval(changeComputerHand, 50); 
  }, 1000); // 1초 이전에 여러번 클릭하게 되면 setTimeout은 제거되지 않음
};

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

예시의 문제점

intervalID변수가 1개 뿐이므로 버튼을 여러 번 눌러도 마지막 값만 저장이 된다


1. 직전 setInterval을 한 번 더 제거하여 중복 실행 해결

const clickButton = () => {
  clearInterval(intervalId);
  setTimeout(() => {
    clearInterval(intervalId); // intervalId를 한 번 더 제거
    intervalId = setInterval(changeComputerHand, 50);
  }, 1000);
};

콘솔로 찍어보면 좀 더 쉽게 이해가 가능하다.

const clickButton = () => {
  console.log('out', intervalId);
  clearInterval(intervalId);
  setTimeout(() => {
    console.log('in', intervalId);
    clearInterval(intervalId);
    intervalId = setInterval(changeComputerHand, 50);
  }, 1000);
};

1초 이내에 4번을 연달아 클릭해 보면

같은 intervalId 변수가 4번 중복되어 제거되고,
1초가 되었을 때, 내부에서 서로 다른 intervalId 변수가 1번씩 제거됨을 알 수 있다.


2. removeEventListener로 중복 실행 해결

let intervalId = setInterval(changeComputerHand, 50);

const clickButton = () => {
  clearInterval(intervalId);
  $rock.removeEventListener('click', clickButton);
  $scissors.removeEventListener('click', clickButton);
  $paper.removeEventListener('click', clickButton);

  // setTimeout이 실행되기 전까지는 EventListener가 동작하지 않는다.
  setTimeout(() => {
    $rock.addEventListener('click', clickButton);
    $scissors.addEventListener('click', clickButton);
    $paper.addEventListener('click', clickButton);
    intervalId = setInterval(changeComputerHand, 50);
  }, 1000);
};

아예 event 자체가 일어나지 않게끔 해 주는 방식이다.


3. flag 변수로 중복 실행 해결

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

2번 방식이 Event 자체가 일어나지 않게끔 하는 방법이였다면,
이번에는 event는 발생하지만, flag 변수를 활용하여 함수 내용이 실행되지 않게끔 한 방식이다.

profile
Blockchain Dev Journey

0개의 댓글