[41장] 타이머

Sheryl Yun·2022년 10월 20일
0
post-thumbnail

호출 스케줄링

함수를 바로 호출하지 않고 일정 시간 이후 호출되도록 함수의 호출을 예약하는 것

왜 함수를 '예약'해서 사용할까?

자바스크립트 엔진은 단 하나의 콜 스택을 갖기 때문에 두 가지 이상의 태스크를 동시에 실행할 수 없다.

이러한 동기적(synchronous) 방식은 한 작업이 끝날 때까지 다음 작업이 실행되지 못하는 한계가 있다.

브라우저의 여러 장치를 사용하면 자바스크립트의 함수를 비동기적(asynchronous)으로 호출하여 한 작업이 끝나지 않았어도 다음 작업을 계속 이어갈 수 있다.

타이머 함수는 브라우저의 Web API에 속하는 기능으로, 실행 순서에 영향을 받지 않는 비동기적 방식으로 작동한다.

타이머 함수

호출 스케줄링을 통해 예약되어 일정 시간 이후에 호출되는 함수로 setTimeout과 setInterval 2가지가 있다.

setTimeout

딜레이 시간이 지나면 콜백 함수를 단 한 번 호출한다.

형태
setTimeout(콜백 함수[, 딜레이 시간, 파라미터1, 파라미터2, ..])

  • 콜백 함수

    • 필수 값
    • 딜레이 시간이 만료되면 한번 호출된다.
  • 딜레이 시간

    • 선택 값
    • 인수가 없으면 기본값은 0

      주의
      delay가 0초라고 해서 지연 시간이 '없는' 게 아니다.
      delay는 밀리초(ms) 단위인데(1초 = 1000ms)
      delay가 4ms(0.004초) 이하이면 최소 지연 시간 4ms가 지정된다.

  • 파라미터1, 파라미터2, ...

    • 선택 값
    • 콜백 함수에 전달할 인수 목록

clearTimeout
setTimeout을 변수에 할당하면 해당 함수의 타이머를 식별할 수 있는 고유 id가 담긴다.
이 id를 clearTimeout 함수에 인수로 전달하면 해당 setTimeout을 취소할 수 있다.

// setTimeout을 선언하고 timerId 변수에 담기
const timerId = setTimeout(() => console.log('Hi!'), 1000);

// clearTimeout에 timerId를 전달 -> setTimeout의 호출을 취소
// 결과: 1초 뒤에 'Hi!'가 콘솔에 찍히지 않는다 (setTimeout의 실행문이 종료됨)
clearTimeout(timerId); 

setInterval

딜레이 시간이 지날 때마다 콜백 함수를 반복 호출한다. (인수 설명은 setTimeout과 동일)

형태
setInterval(콜백 함수[, 딜레이 시간, 파라미터1, 파라미터2, ..])

clearInterval
setInterval를 변수에 할당하면 setTimeout과 마찬가지로 타이머를 식별할 수 있는 고유 id가 담긴다.
이 id를 clearInterval 함수에 전달하면 해당 setInterval를 취소할 수 있다.

let count = 1;

// 1초마다 setInterval의 콜백 함수 호출
const timeoutId = setInterval(() => {
	console.log(count);
    
    // 특정 조건이 되면 setInterval 취소
    if (count++ === 5) clearInterval(timeoutId);
}, 1000);

디바운스와 스로틀

짧은 시간 간격으로 발생하는 이벤트들을 그룹화하여 과도한 이벤트 핸들러의 호출을 방지하기 위한 기법이다.

디바운스(Debounce)

일정 시간 뒤에 '한 번' 호출 => setTimeout 함수 사용

const debounce = (callback, delay) => {
	let timerId;
  
    return (event) => {
    	if (timerId) clearTimeout(timerId);
        timerId = setTimeout(callback, delay, event); // *
    };
};

$input.oninput = debounce((e) => {
	$msg.textContent = e.target.value;
}, 300);
  • 이벤트가 짧은 시간 간격으로 딜레이 시간 내에서 계속해서 발생하고 있을 때는 callback 함수를 호출하지 않다가 (=> clearTimeout 함수로 타이머를 계속 취소 + 새로운 타이머 재설정)
  • 마지막 이벤트 발생 이후 딜레이 시간(300ms) 동안 아무 이벤트가 발생하지 않으면 콜백 함수를 한 번 호출한다.
  • 용도: 짧은 시간에 많은 이벤트가 발생하고 + 완료 시점이 있는 이벤트
    • resize: 도형 크기 조절
    • input: 입력 창, 검색 자동 완성
    • button: 중복 클릭 방지

스로틀(Throttle)

여러 번의 이벤트가 연속적으로 일어나도 콜백 함수는 일정 시간마다 호출

const throttle = (callback, delay) => {
	let timerId;
    
    return (event) => {
    	if (timerId) return; 
        timerId = setTimeout(() => {
        	callback(event);
            timerId = null;
        }, delay, event);
    }
}
  • 이벤트가 짧은 시간 간격으로 계속해서 발생하고 있을 때 일정 시간 단위로만 콜백 함수가 호출되도록 한다.

  • 첫 번째 이벤트가 발생하면 콜백 함수 호출 => 딜레이 시간 동안 발생하는 이벤트들에는 콜백 함수 호출하지 않음 => 딜레이 시간 후 처음 발생한 이벤트 때 다시 콜백 함수 호출 => 반복

  • 용도: 짧은 시간에 많은 이벤트가 발생하고 + 특정 완료 시점은 없는 이벤트

    • 지도 드래그 이동 (순식간에 무수한 scroll 좌표 찍힘)
    • 무한 스크롤
profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글