업무를 처리하면서 지난 번에 정리한 적이 있는 Debounce
를 적용할 일이 생겼었습니다. 직접 적용하면서 생각처럼 잘 적용이 되지 않았던 부분에 대해 정리하기 위해 이 게시글을 작성하게 되었습니다.
아래의 간단한 예시는 "검색" 버튼을 클릭하거나 "입력창"에서 "Enter" 버튼을 눌렀을 때 검색 내용에 입력 내용이 보여지는 기능을 갖고 있습니다. 또 검색창의 내용이 보여질 때마다 콘솔에 입력 내용을 출력하였습니다.
만약 입력창에 '검색 내용'을 입력하고 'Enter' 키를 연속해서 누르게 되면 아래와 같은 콘솔이 출력됩니다.
만약 이때 비용이 큰 ajax
요청을 하게 된다면 성능에 문제가 생길 수 있습니다. 그래서 여기에 debounce
를 적용시키려고 하였습니다.
debounce
를 적용하기 이전엔 다음과 같은 구조로 구현이 되어 있었습니다.
searchInput.addEventListener('keyup', function (event) {
if (event.keyCode === 13) {
// "검색" 버튼을 클릭하는 함수
clickSearchBtn()
}
})
여기에서 debounce
를 처음에 clickSearchBtn
함수에 적용하려 했던 것이 문제였습니다.
searchInput.addEventListener('keyup', function (event) {
if (event.keyCode === 13) {
// "검색" 버튼을 클릭하는 함수
_.debounce(clickSearchBtn(event), 300)();
}
})
이런 식으로 구현을 하고 'Enter'를 3번 연속 눌렀을 땐 0.3초의 간격을 두고 clickSearchBtn
함수가 3번 연속으로 실행되었습니다. 그 이유는 이벤트 콜백 함수 안에서 계속해서 새로운 debounce
를 만들어내기 때문입니다.
이를 해결하기 위해선 이벤트를 등록하는 스코프 또는 그보다 더 넓은 스코프에서 debounce
에 대한 선언을 해주어야 합니다.
// debounce를 미리 선언
const debounceSearch = _.debounce((event) => {
clickSearchBtn(event);
}, 300)
searchInput.addEventListener('keyup', function (event) {
if (event.keyCode === 13) {
debounceSearch(event);
}
})
또는 이벤트 콜백 함수 자체에 debounce
를 적용할 수 있습니다.
searchInput.addEventListener(
'keyup',
_.debounce(function (event) {
clickSearchBtn(event)
}, 300)
)