<aside>
💡 디바운스는 input 이벤트에(리액트에선 onChange
), 스로틀은 scroll 이벤트에 자주 사용된다.
</aside>
디바운스는 아무리 많은 이벤트가 발생해도 마지막 이벤트만 실행하는 반면, 스로틀은 적어도 n
밀리초 마다 정기적으로 기능 실행을 보장하는 점이 가장 큰 차이점. 참고로 Lodash 라이브러리에 디바운스와 스로틀 메서드가 포함되어 있다.
이벤트가 연속적으로 발생해도 항상 마지막 이벤트만 처리 이벤트를 그룹화하여 특정 시간이 지난 후 하나의 이벤트만 발생하도록 하는 기술
function debounce(callback, ms) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
callback(...args);
}, ms);
};
}
// input에 타이핑을 멈추고 ms초 후에 이벤트 처리. 타이핑(이벤트 발생) 도중엔 아무일도 일어나지 않음
input.addEventListener('input', debounce(e => console.log(e.target.value), 1000))
// addEventListener 코드를 실행한 순간 debounce 함수가 실행되고 내부 함수를 반환함
// 즉 이벤트 핸들러엔 debounce 함수가 반환한 내부 함수가 할당됨
// 이벤트가 발생하면 내부 함수 인자 (...args)에 event 객체가 전달됨
타이핑을 멈춘 시점(이벤트가 발생하지 않는 시점)부터 ms초(위 예제에선 1초) 후에 이벤트를 처리한다.
clearTimeout
을 통해 이전 이벤트 처리 로직을 취소한다.ms
초(위 예시에선 1초)가 지났을 때 이벤트 처리(callback 실행)가 시작된다.<input>
태그에 입력한 API 요청 제한스로틀 : 일정 (시간)간격으로 이벤트 처리 이벤트를 일정한 주기마다 발생하도록 하는 기술
function throttle(callback, ms) {
let timeout;
return function (...args) {
if (!timeout) {
timeout = setTimeout(() => {
callback(...args);
timeout = null;
}, ms);
}
};
}
// input창에 타이핑(이벤트)을 계속 하더라도 항상 ms초 간격으로 이벤트 처리
input.addEventListener('input', throttle(e => console.log(e.target.value), 1000))
// addEventListener 코드를 실행한 순간 throttle 함수가 실행되고 내부 함수를 반환함
// 즉 이벤트 핸들러엔 throttle 함수가 반환한 내부 함수가 할당됨
// 이벤트가 발생하면 내부 함수 인자 (...args)에 event객체가 전달됨
이벤트(위 예제에선 타이핑)가 지속적으로 발생해도 항상 지정한 ms초 마다 이벤트에 대한 처리가 이뤄진다
ms
초가 지난 후 이전 이벤트 처리를 완료하면, 타임아웃 ID가 null
로 변경되고 이 시점부터 새로운 이벤트를 처리할 수 있는 상태가 된다.ms
초 간격으로 처리된다.