Rate limiting with debounce

Rate limiting by awaiting a function call and clearing a timeout

// without debounce

const callback = () => {
  console.log("Handle event")
}

callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event
callback() // Handle event

// with debounce
const debouncedCallback = debounce(callback, 1000);

debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback() 
debouncedCallback()  

// after 1 second
// Handle event

Limiting function calls

스케쥴링 함수 중 하나인 setTimeout을 이용하여 함수 호출을 지연시킬 수 있다. 그리고 클로저를 이용하여 함수의 호출 상태를 관리 한다.

function debounce(fn, wait) {
  let timeout = null
  let debounceFn = null

  const clear = () => {
    // 함수 호출을 취소하고 상태를 초기화 한다.
     if (timeout) {
      clearTimeout(timeout);

      debouncedFn = null;
      timeout = null;
    }   
  }
  const debounceWrapper = function () {
    // ...

    // 이전에 기록된 함수 호출을 취소하고 상태를 초기화 한 후
    clear();

    // 새로 함수를 기록한다. 
    debouncedFn = function () {
      fn();
    };

    // 그리고 함수 호출을 스케쥴링 한다.
    timeout = setTimeout(function () {
      const call = debouncedFn as Function;
      debouncedFn = null;
      return call();
    }, wait);
  };

}

따라서 함수를 연속적으로 호출하더라도 이전 함수 호출을 취소하고 새로운 함수를 스케쥴링하기 때문에 함수호출을 한 번만 발생시킬 수 있다.