41.1. 호출 스케줄링
- 호출 스케줄링 (scheduling a call) : 함수 호출 예약, 타이머 함수 사용
- 타이머 함수는 호스트 객체
- 자바스크립트 엔진은 싱글 스레드이므로 타이머 함수는 비동기 처리 방식으로 동작함
41.2. 타이머 함수
41.2.1. setTimeout / clearTimeout
setTimeout(func|code[, delay, param1, param2, ...])
- 인수로 전달받은 시간 이후 콜백 함수가 단 한 번만 동작하도록 호출 스케줄링되는 타이머 함수
func
- 타이머 이후 호출될 콜백 함수
- 문자열 가능하지만 권장하지 않음
delay
- 타이머 만료 시간
- 생략한 경우 기본값 0 지정
- 4ms 이하인 경우 최소 지연 시간 4ms 지정
param1, param2, ...
- 콜백 함수에 전달할 인수
- IE9 이하에서는 전달 불가
- 생성된 타이머를 식별할 수 있는 고유한 타이머 id 반환
- 브라우저 환경인 경우 숫자
- Node.js 환경인 경우 객체
clearTimeout(id)
41.2.2. setInterval / clearInterval
setInterval(func|code[, delay, param1, param2, ...])
- 인수로 전달받은 시간마다 취소될 때까지 반복 동작하도록 호출 스케줄링 되는 타이머 함수
- 인수는
setTimeout과 동일함
clearInterval(id)
41.3. 디바운스와 스로틀
- 짧은 간격으로 연속해서 발생하는 이벤트를 그룹화하여 과부하 방지하는 프로그래밍 기법
- 디바운스와 스로틀 구현에는 타이머 함수가 사용됨
41.3.1. 디바운스
- 짧은 간격으로 연속해서 이벤트가 발생하면 함수를 호출하지 않고 일정 시간 이후에 마지막 한 번만 호출함
- input 이벤트 예시
- 일정 시간 동안 텍스트 입력 필드에 입력하지 않으면 완료된 것으로 간주
debounce 두 번째 인수로 전달한 시간(delay)보다 짧은 간격으로 이벤트가 발생하면 이전 타이머 취소
- delay 이후 input 이벤트가 발생하지 않으면 한 번만 호출됨
- resize, input 입력 값으로 ajax 요청, 버튼 중복 클릭 방지 처리 등에 유용함
- Underscore의
debounce, Lodash의 debounce 사용 권장
const debounce = (callback, delay) => {
let timerId;
return (...args) => {
if (timerId) clearTimeout(timerId);
timerId = setTimeout(callback, delay, ...args);
};
};
$input.oninput = debounce(e => {
$msg.textContent = e.target.value;
}, 300);
41.3.2. 스로틀
- 짧은 간격으로 연속해서 이벤트가 발생하더라도 일정 시간 단위로 호출 주기를 만들어 최대 한 번만 호출함
- scroll 이벤트 예시
- 인수로 전달한 시간(delay)이 경과하기 전에 이벤트가 발생하면 아무것도 하지 않음
- delay 시간이 경과했을 때 콜백 함수를 호출하고 새로운 타이머 재설정
- delay 시간 간격으로 콜백 함수가 호출됨
- scroll 이벤트 처리나 무한 스크롤 구현 등에 유용함
- Underscore의
throttle, Lodash의 throttle 사용 권장
const throttle = (callback, delay) => {
let timerId;
return (...args) => {
if (timerId) return;
timerId = setTimeout(() => {
callback(...args);
timerId = null;
}, delay);
};
};
let throttleCount = 0;
$container.addEventListener('scroll', throttle(() => {
$throttleCount.textContent = ++throttleCount;
}, 100));
[출처] 모던 자바스크립트, Deep Dive