🛠️ 처음부터 만드는 Debounce — 연속 호출을 마지막 한 번만 실행하기
# Debounce 만들기
Throttle과 달리, Debounce는 마지막 호출만 실행합니다. 검색창 입력, 폼 저장, 리사이즈 이벤트 등 "연속 이벤트의 끝"을 기다려야 할 때 유용합니다.
```javascript
function debounce(fn, delay) {
let timeoutId = null;
return function (...args) {
// 이전 타이머 취소
clearTimeout(timeoutId);
// 새 타이머 설정 — delay 후 실행
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 사용 예
const handleSearch = debounce((query) => {
console.log(`검색: ${query}`);
}, 300);
input.addEventListener('input', (e) => {
handleSearch(e.target.value);
});
// 사용자가 타이핑 멈춘 후 300ms 뒤에 한 번만 실행
```
때로는 "첫 호출은 즉시, 마지막은 지연"이 필요합니다:
```javascript
function debounce(fn, delay, immediate = false) {
let timeoutId = null;
let lastResult;
return function (...args) {
const callNow = immediate && !timeoutId;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
if (!immediate) fn.apply(this, args);
timeoutId = null;
}, delay);
if (callNow) {
lastResult = fn.apply(this, args);
}
return lastResult;
};
}
// 버튼 클릭 — 첫 번은 즉시, 연속 클릭은 무시
const debouncedSave = debounce(saveData, 500, true);
button.addEventListener('click', debouncedSave);
```
| 패턴 | 동작 | 사용처 |
|------|------|--------|
| Throttle | 일정 시간마다 실행 | 스크롤, 마우스 움직임 |
| Debounce | 마지막 호출만 실행 | 검색, 저장, 유효성 검사 |
실무에선 둘 다 필수입니다. 최신 브라우저에선 [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)과 조합해 성능을 더 최적화할 수 있습니다.
Throttle과 달리, Debounce는 마지막 호출만 실행합니다. 검색창 입력, 폼 저장, 리사이즈 이벤트 등 "연속 이벤트의 끝"을 기다려야 할 때 유용합니다.
기본 구현
```javascript
function debounce(fn, delay) {
let timeoutId = null;
return function (...args) {
// 이전 타이머 취소
clearTimeout(timeoutId);
// 새 타이머 설정 — delay 후 실행
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 사용 예
const handleSearch = debounce((query) => {
console.log(`검색: ${query}`);
}, 300);
input.addEventListener('input', (e) => {
handleSearch(e.target.value);
});
// 사용자가 타이핑 멈춘 후 300ms 뒤에 한 번만 실행
```
즉시 실행 옵션
때로는 "첫 호출은 즉시, 마지막은 지연"이 필요합니다:
```javascript
function debounce(fn, delay, immediate = false) {
let timeoutId = null;
let lastResult;
return function (...args) {
const callNow = immediate && !timeoutId;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
if (!immediate) fn.apply(this, args);
timeoutId = null;
}, delay);
if (callNow) {
lastResult = fn.apply(this, args);
}
return lastResult;
};
}
// 버튼 클릭 — 첫 번은 즉시, 연속 클릭은 무시
const debouncedSave = debounce(saveData, 500, true);
button.addEventListener('click', debouncedSave);
```
Throttle과의 차이
| 패턴 | 동작 | 사용처 |
|------|------|--------|
| Throttle | 일정 시간마다 실행 | 스크롤, 마우스 움직임 |
| Debounce | 마지막 호출만 실행 | 검색, 저장, 유효성 검사 |
실무에선 둘 다 필수입니다. 최신 브라우저에선 [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)과 조합해 성능을 더 최적화할 수 있습니다.
👁 0 views
Comments (0)
💬
No comments yet.
Be the first to comment!