let 아이디 = setInterval(함수, 밀리초);
clearInterval(아이디);
setInterval 함수는 사실 반환값이 있다. 반환값은 타이머에 대한 아이디(숫자)로, 나중에 이 값을 사용해 타이머를 제거할 수 있다. 이와 마찬가지로 setTimeout 함수도 clearTimeout 함수로 취소할 수 있다.
/* 타이머 멈췄다가 다시 실행하기 */
let intervalid = setInterval(computerHandImg, 50);
const clickButton = () => {
clearInterval(intervalid);
// 점수 계산 및 화면 표시
setTimeout(() => {
intervalid = setInterval(computerHandImg, 50);
}, 1000);
}
$scissors.addEventListener('click', clickButton);
$rock.addEventListener('click', clickButton);
$paper.addEventListener('click', clickButton);
그림이 멈춘 동안 버튼을 여러번 클릭하고 버튼을 또 클릭하면 일시정지 되지않는 현상이 나타난다.
이런 버그가 나타나게 되는 이유는.. 버튼을 클릭할 때마다
clearInterval 은 interval 만 제거할 수 있다. 따라서 버튼을 누른 횟수만큼 setTimeout 은 여러번 호출되고 각각 1초 뒤에 setInterval 을 하게 되어 그림이 매우 빠른 속도로 돌아가게 된다.
위의 코드의 자세한 작동 순서는
1. clickButton 5번 호출: 인터벌 1번, 2번, 3번, 4번, 5번(얘만 intervalid) (덮어쓰임 현상)
2. 그 다음 1초 뒤에 버튼을 클릭하면 5번만 취소
해결방법 1
removeEventListener 메서드를 사용한다.
클릭 이벤트를 제거했다고 생각했다면 큰 오산이다.
fun(1) === fun(1) 은 false 의 결괏값이 나온다. 객체부분에서 공부했었다. (객체 사이의 비교 연산은 false이다.)
이렇게 b가 a를 참조할 수 있어야 지워지는 것이다.
정말 많이 하는 실수이므로 기억해두자.
해결방법 2
플래그 변수를 이용한다.
플래그변수: 참거짓이냐에 따라서 안에 코드를 실행해줄지 말지를 결정하는 변수
let intervalid = setInterval(computerHandImg, 50);
let clickable = true;
const clickButton = () => {
if (clickable) {
clearInterval(intervalid);
clickable = false;
setTimeout(() => {
clickable = true;
intervalid = setInterval(computerHandImg, 50);
}, 1000);
}
}
$scissors.addEventListener('click', clickButton);
$rock.addEventListener('click', clickButton);
$paper.addEventListener('click', clickButton);
유튜브 댓글 참고
clickButton을 5번 호출하면 인터벌이 쌓이고 다시 버튼 호출했을 때 마지막 인터벌만 사라진다고 하셨는데 setTimeout은 clear를 안해줬지만 setTimeout에 실행되는 인터벌은 아이디를 변수에 저장해뒀고, 다시 버튼을 눌렀을 땐 인터벌은 해제되어야 하는 것 아닌가요? 예를 들어 1번 인터벌 실행 중 1번 버튼 누름->1번인터벌취소->setTimeout의 새로운 2번인터벌실행->2번 버튼 누름->2번인터벌취소 이런 식으로 버튼을 누르면 상쇄가 되는 것 같아서요. setTimeout은 인터벌을 실행시키는 거고 이게 clear되지 않는다고 해서 인터벌이 취소되지 않는다는 게 무슨 말인지를 모르겠습니다ㅠㅠ
연달아 누를 때입니다. 연달아누르는 경우는 setTimeout 내부는 클릭보다 나중에 실행되는 것이라 아이디가 대입되는 것도 나중입니다.
연달아 누를 경우 setInterval이 1초 뒤 실행되기 때문에 버튼을 눌렀을 때 실행되는 clearInterval은 지울 인터벌이 없다.
'🤹🏻♀️ Javascript' 카테고리의 다른 글
객체 순회하기 (0) | 2021.11.06 |
---|---|
클래스, const 객체, 메서드, map 메서드 (0) | 2021.11.06 |
제로초 자바스크립트 6장 (로또 추첨기) (0) | 2021.10.23 |
제로초 자바스크립트 5장 (숫자야구) (0) | 2021.10.18 |
제로초 자바스크립트 4장 (계산기) (0) | 2021.10.18 |