Lodash debounce 이해하기
you don't need
시리즈에 구현된 lodash의 debounce 함수를 파헤쳐 보자.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
timeout = null;
console.log(context, args); // 1
if (!immediate) func.apply(context, args);
}, wait);
if (immediate && !timeout) func.apply(context, args);
};
}
const onChange = (e) => { console.log(e) } // 2
const element = document.getElementById('element_id') // <div id="element_id>element</div>
element.addEventListener('click', debounce(onChange))
// 1: <div id="element_id>element</div>, Argument { MouseEvent, callee, Symbol }
// 2: MouseEvnet
- 첫번째 출력:
element click 시 debounce 함수에서 리턴된 내부 함수가 호출된다.
addEventListener
의 콜백함수에서this
는 리스너에 바인딩되된 element 요소를 가리킨다. (참고)
또한 args는 리턴된 내부함수가 받아온 arguments를 가리킨다. func.apply(context, args)
:
wait시간이 만족되었다면 debounce 함수의 첫번째 인자로 전달받은 함수를 element를 바인딩하고 argument를 parameter로 전달하여 실행한다. 두번째console.log
가 출력된다.clearTimeout(timeout)
:
지정된 setTimeout 함수의 실행을 중지한다.if (immediate && !timeout) func.apply(context, args)
:
등록된 timeout이 없으며, immediate===true 이면 즉시 실행한다.
Arrow Function
function debounce(func, wait, immediate) {
var timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(()=> {
timeout = null;
console.log(this, arguments);
if (!immediate) func.apply(this, arguments);
}, wait);
if (immediate && !timeout) func.apply(this, arguments);
};
}
화살표 함수를 이용해서 this, arguments 값을 복사하지 않고도 쓸 수 있다.
Full ES6 Syntax
const debounce = (func, wait) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
func(...args);
}, wait);
};
};
이전의 arrow function 문법을 사용하니, ES5와 ES6 문법이 섞여있다는 피드백을 받았다.
ES6의 Rest, Spread 문법을 사용하여 새롭게 구현하였다.