게으른개발너D

[Function] Debounce ⭐️ 본문

알고리즘/과제

[Function] Debounce ⭐️

lazyhysong 2023. 7. 4. 14:20

https://leetcode.com/problems/debounce/description/

 

Debounce - LeetCode

Can you solve this real interview question? Debounce - Given a function fn and a time in milliseconds t, return a debounced version of that function. A debounced function is a function whose execution is delayed by t milliseconds and whose execut

leetcode.com

Given a function fn and a time in milliseconds t, return a debounced version of that function.

debounced function is a function whose execution is delayed by t milliseconds and whose execution is cancelled if it is called again within that window of time. The debounced function should also receive the passed parameters.

For example, let's say t = 50ms, and the function was called at 30ms, 60ms, and 100ms. The first 2 function calls would be cancelled, and the 3rd function call would be executed at 150ms. If instead t = 35ms, The 1st call would be cancelled, the 2nd would be executed at 95ms, and the 3rd would be executed at 135ms.

 

The above diagram shows how debounce will transform events. Each rectangle represents 100ms and the debounce time is 400ms. Each color represents a different set of inputs.

Please solve it without using lodash's _.debounce() function.

 

 

Example 1:

Input: 
t = 50
calls = [
  {"t": 50, inputs: [1]},
  {"t": 75, inputs: [2]}
]
Output: [{"t": 125, inputs: [2]}]
Explanation:
let start = Date.now();
function log(...inputs) { 
  console.log([Date.now() - start, inputs ])
}
const dlog = debounce(log, 50);
setTimeout(() => dlog(1), 50);
setTimeout(() => dlog(2), 75);

The 1st call is cancelled by the 2nd call because the 2nd call occurred before 100ms
The 2nd call is delayed by 50ms and executed at 125ms. The inputs were (2).

Example 2:

Input: 
t = 20
calls = [
  {"t": 50, inputs: [1]},
  {"t": 100, inputs: [2]}
]
Output: [{"t": 70, inputs: [1]}, {"t": 120, inputs: [2]}]
Explanation:
The 1st call is delayed until 70ms. The inputs were (1).
The 2nd call is delayed until 120ms. The inputs were (2).

Example 3:

Input: 
t = 150
calls = [
  {"t": 50, inputs: [1, 2]},
  {"t": 300, inputs: [3, 4]},
  {"t": 300, inputs: [5, 6]}
]
Output: [{"t": 200, inputs: [1,2]}, {"t": 450, inputs: [5, 6]}]
Explanation:
The 1st call is delayed by 150ms and ran at 200ms. The inputs were (1, 2).
The 2nd call is cancelled by the 3rd call
The 3rd call is delayed by 150ms and ran at 450ms. The inputs were (5, 6).

Constraints:

  • 0 <= t <= 1000
  • 1 <= calls.length <= 10
  • 0 <= calls[i].t <= 1000
  • 0 <= calls[i].inputs.length <= 10

 

solution

/**
 * @param {Function} fn
 * @param {number} t milliseconds
 * @return {Function}
 */
var debounce = function(fn, t) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => fn(...args), t);
    }
};

/**
 * const log = debounce(console.log, 100);
 * log('Hello'); // cancelled
 * log('Hello'); // cancelled
 * log('Hello'); // Logged at t=100ms
 */

 

solution2

/**
 * @param {Function} fn
 * @param {number} t milliseconds
 * @return {Function}
 */
const debounce = (fn, t) => {
  let timeout;
  return (...args) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      fn.apply(this, args);
    }, t);
  };
};

 


풀이

1. debounce에는 fn과 t라는 두 가지 인수가 사용된다.
2. fn은 디바운스할 함수
3. t는 마지막으로 호출된 후 fn을 실행하기 전에 대기할 시간
4. 디바운스 함수는 임의의 수의 argumnet(...args)를 사용하는 새 함수를 반환한다.
5. 반환된 기능 내에서는 setTimeout을 사용하여 타이머를 설정한다. 타이머는 처음에 t 밀리초로 설정된다.

6. 반환된 기능이 호출될 때마다 clearTimeout 기능이 호출되어 타이머를 t밀리초로 재설정한다.
7. 반환된 기능을 다시 호출하지 않고 타이머가 경과되면 타이머의 콜백 기능이 실행된다. 콜백 함수는 반환된 함수로 전달된 인수를 사용하여 fn을 호출한다.

 

1. Debounce

짧은 시간 내에 어떠한 기능이 여러 번 호출되어 성능 문제나 예상치 못한 동작이 발생한 적이 있을 것이다. 이 문제는 특히 스크롤, 크기 조정 또는 입력같은 이벤트를 작업할 때 일반적으로 발생하는 문제다.

함수 호출 빈도를 제어하고 이러한 문제를 방지하는 기술이 debounce이다.

 

디바운스란?

디바운스는 함수가 호출되는 속도를 제한하는 방법이다. 별도의 함수 호출 없이 일정 시간이 경과할 때까지 함수의 실행을 지연시키는 방식이다. 이 시간 내에 다른 함수 호출이 발생하면 타이머가 재설정되고 함수 실행이 다시 지연된다.
- 디바운스는 다음과 같이 함수가 너무 자주 호출되지 않도록 하려는 상황에서 유용하다.
- 키 누르기, 마우스 이동 또는 버튼 클릭과 같은 사용자 입력 이벤트 처리
- 모든 함수 호출에 대해 수행할 필요가 없는 값비싼 계산 또는 네트워크 요청 처리

 

 

2. [Function] apply()

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

 

Function.prototype.apply() - JavaScript | MDN

apply() 메서드는 주어진 this 값과 배열 (또는 유사 배열 객체) 로 제공되는 arguments 로 함수를 호출합니다.

developer.mozilla.org

apply() 메서드는 주어진 this 값과 배열로 제공되는 arguments 로 함수를 호출한다.

이미 존재하는 함수를 호출할 때 다른 this 객체를 할당할 수 있습니다. this 는 현재 객체, 호출하는 객체를 참조한다.

apply 를 사용해, 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속시킬 수 있다.

 

ex1)

const numbers = [5, 6, 2, 3, 7];

const max = Math.max.apply(null, numbers);

console.log(max);
// Expected output: 7

const min = Math.min.apply(null, numbers);

console.log(min);
// Expected output: 2

 

ex2) 배열에 배열을 붙이기

push 를 사용하여 요소를 배열에 추가 할 수 있다. push 는 가변 인수를 허용하기 때문에 여러 요소를 동시에 추가 할 수 있다.

그러나 push 에 배열을 전달하면 요소를 개별적으로 추가하는 대신 실제로 해당 배열을 단일 요소로 추가하므로 결국 배열 내부에 배열로 끝난다.

이것은 우리가 원하는 방법이 아니므로 우리는 concat을 쓸 수 있지만, 실제로는 추가할 배열이 기존 배열에 추가되지 않고 새 배열을 만들어 반환한다. 그러나 우리는 기존 배열에 추가할 배열을 추가하고 싶다. 그럴때 apply를 사용하면 된다.

const array = ['a', 'b'];
const elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
Comments