검색 기능을 구현 할때 불필요한 요청을 줄이기위해 debounce
를 구현해서 요청을 줄인다. 보통은 라이브러리(Lodash)를 많이 사용하지만 직접 구현 해보기로 했다
function debounce(callback, delay = 500) {
let timer = null
return (...args) => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
callback(...args)
}, delay)
}
}
debouce를 구현하면 위와같은 코드로 구현 할 수 있다.
동작원리를 간단하게 설명 하면
처음에 timer
를 선언해주고 함수를 return 한다 →
만약 timer
가 있으면 clearTimeout
해주어 setTimeout
을 종료한다. →
timer
에 새로운 setTimeout
을 넣어준다.
이런 과정을 통해서 여러 요청이 들어와도 이전에 있던 요청은 clearTimeout
으로 종료해주고 새로운 setTimeout
을 실행한다.
🤖 "timer는 어떻게 동작하는거지?" 라는 의문이 생긴다.
바로 Closure
개념을 이용한 것이다.
Closure
: 생명주기가 끝난 렉시컬 스코프의 환경을 기억해서 내부함수가 외부함수에 접근할수있는 개념
자바스크립트는 Lexical scope
를 따른다, 어디서 호출 되었는지 보다 어디서 선언 되었는지에 따라 상위스코프가 결정된다.
debouce
의 timer
또한 생명주기가 끝난 함수 이지만 반환된 함수를 통해서 접근 할수있는 것이다.
♻️ 직접 debounce를 사용해 보면
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input class="input" type="text" />
<script>
// 여기에 javascript code 가 작성된다.
</script>
</body>
</html>
function debounce(callback, delay = 500) {
let timer = null
return (...args) => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
callback(...args)
}, delay)
}
}
const onClick = (e) => {
console.log(e.target.value)
}
const debounceInstance = debounce(onClick)
const $input = document.querySelector('.input')
$input.addEventListener('input', debounceInstance)
다음과 같이 사용 할 수 있다.
🚨여기서 주의해야할 점은 함수의 호출
이다.
addEventListener
에 인자로 들어가 있는 debounceInstance
는 callback함수로 들어가 있는것이지 함수의 호출이 된것이 아니다.
(함수의 호출을 작성하려면 debounceInstance()
으로 인자로 넣어야한다)
input
이벤트가 발생할때마다 tiemr
재선언 되어서 const timer = null
이 계속해서 실행되는것이 아닐까라는 의문이 들수도 있다.
그래서 이해를 돕기 위해 debounceInstance
변수에 debounce
를 넣어서 사용해주었다.
debounce
는 한번만 호출되고 debounce
가 반환한 함수 즉 아래 코드와 같이 함수만 반복적으로 실행된다고 생각된다
const debounceInstance = (...args) => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
callback(...args)
}, delay)
}
이런식으로 동작하기에 timer
는 재선언되지 않고, debounce
에서 반환된 함수를 통해 timer
에 접근해서 debounce
를 구현할수 있었던 것이다.
추가적으로 보면 좋은자료