디바운스와 스로틀은 ES6문법은 아닙니다. 하지만 지연 처리를 효율적으로 구현할 수 있습니다.
어떤 내용을 입력하다가 일정 시간동안 입력이 없으면 마지막에 입력된 내용을 바탕으로 한번만 서버요청을 하는 방법입니다. 네이버의 추천 검색어, 연관 검색어의 창을 생각하면 이해하기가 쉽습니다.
export function debounce(func, delay){
let inDebounce;
return function(...args){ //
if(inDebounce){
clearTimeout(inDebounce);
}
inDebounce = setTimeout(()=>func(...args),dalay);
}
}
const run = debounce(val => console.log(val),100);
run('1');
run('2');
run('3');
// 100ms 이후
// 출력 : 3
inDebounce
를 공유합니다.clearTimeout
으로 제거후 다시 작업을 실행합니다.run()
함수를 호출하지 않으면 최종적으로 호출된 run()
함수에 대한 결과만 볼 수 있습니다.디바운스 개념과 비슷하지만 ‘입력되는 동안에도 바로 이전에 요청한 작업을 주기적으로 실행한다는 점’ 이 다릅니다. 인스타그램과 같이 일명 무한스크롤 기능을 구현할 때 사용합니다. 만약 디바운스로 구현되어 있다면 ‘스로틀링’이 멈추지 않는한 다음 타임라인 로딩은 진행되지 않습니다.
디바운스와 다르게 스로틀은 첫번째 요청이 지연 실행되는 동안 중복된 요청을 무시하고, 실행 이후에 첫번째로 호출되는 요청을 동일하게 지연 실행하여 구간 내에서는 중복요청과정을 생략합니다.
function throttle(func, delay){
let lastFunc;
let lastRan;
return function(...arg){
const context = this;
if(!lastRan){ //마지막 실행시간이 없다면
func.call(context,..args); // 함수 실행
lastRan = Date.now(); //마지막 실행 시간 추가
else{ //마지막 실행시간이 존재한다면
if(lastFunc) clearTimeout(lastFunc);
lastFunc = setTimeout(function(){
if((Date.now() - lastRan) >= delay){ //daley시간 안지났으면 사용못함
func.call(context, ...args);
lastRan = Date.now();
}
}, delay - (Date.now() - lastRan)); //남은 딜레이시간
}
}
}
var checkPostion = () =>{
const offset = 500;
const currentScrollPosition = window.pageYOffset;
const pageBottomPosition = document.body.offsetHeight -window.innerHeight - offset;
if(currentScrollPosition >= pageBottomPosition){ //스크롤 제일 밑에 닿았다면
//fetch('page/next');
console.log('다음 페이지 로딩');
}
};
var infiniteScroll = throttle(checkPosition, 300);
window.addEventListener('scroll', infiniteScroll);
func는 스크롤이 이동할 때 호출되는 서버요청이고 delay는 호출 생략 시간 입니다. 코드를 보면 func() 함수가 처음 실행(!lastRan)될 때 ‘함수를 즉시 실행하고, 실행시간(lastRan)을 저장한다는 점이 다릅니다.
이후(lastRan) 함수를 실행하는 요청이 오면 setTimeout()함수를 실행시켜 지연시간(Date.now() - lastRan)을 계산하고 이 값이 delay보다 커야만 func() 함수를 실행시킵니다.
위에 작성된 함수는 브라우저의 스크롤을 내리면 스크롤이 움직이는 동안 console.log() 함수가 주기적으로 실행되어 다음페이지 로딩 이라는 문장콘솔에 출력되는 것을 확인할 수 있습니다.