Для чего нужна функция debounce и как она работает
02.09.2018
/
oberset
Функция debounce возвращает обертку, которая откладывает вызов исходной функции на определенное время.
Вот как это обычно выглядит в коде:
const myFoo = () => console.log('Called!');
const myFooDebounced = debounce(myFoo, 200);
myFooDebounced();
myFooDebounced(); // выполнится 1 раз через 200 мс
Мы передаем исходную функцию в качестве параметра в debounce и получаем новую функцию-обертку, которая уже будет выполняться с задержкой в 200 мсек. Если в течение этого промежутка времени произойдет несколько вызовов myFooDebounced (как в примере выше), то исходная функция все равно вызовется только 1 раз с задержкой в 200 мс с момента последнего вызова myFooDebounced.
Где требуется применение debounce?
Обычно debounce используют, если исходная функция вызывается чаще, чем это требуется. Например, DOM-события mousemove, resize, scroll генерируют очень частые вызовы обработчиков, поэтому в ряде случаев было бы полезно обернуть такие обработчики в debounce. Другое применение – контроль пользовательского ввода текста: если при изменении поля INPUT требуется передавать на сервер текущее введенное значение, это может создать большое количество однотипных запросов, особенно если пользователь печатает очень быстро. В этом случае тоже весьма кстати будет ограничить число вызовов обработчика с помощью debounce.
Как работает debounce
Теперь, когда мы знаем, где может потребоваться debounce, рассмотрим как эта функция работает изнутри. Вот пример простейшей реализации функции (подобные примеры иногда требуют написать на собеседовании):
const debounce = (callback, delay) => {
let timerId;
return (...args) => {
timerId && clearTimeout(timerId);
timerId = setTimeout(
() => callback(...args),
delay
);
}
};
const foo = (val) => console.log(val);
const debounced1 = debounce(foo, 1000);
const debounced2 = debounce(foo, 2000);
for (let i = 0; i < 10; i++) {
debounced1('Called One!'); // Вызовется через 1 сек
debounced2('Called Two!'); // Вызовется через 2 сек
}
В примере выше, при каждом вызове debounce мы сбрасываем текущий «таймаут» и устанавливаем новый, гарантируя время задержки, переданное в качестве второго параметра. Мы вызываем наши функции-обертки в цикле, но фактически каждая из функций вызовется только 1 раз (через 1 и 2 секунды соответственно).
Готовые реализации debounce
Конечно же, нет смысла писать каждый раз подобную функцию самому (если вы не сидите с листком бумаги на собеседовании), поэтому можно воспользоваться готовым решением. Неплохая реализация debounce есть в библиотеке Lodash.
// Lodash доступна через _
window.addEventListener('resize', _.debounce(e => {
console.log(window.innerWidth, window.innerHeight);
}, 100));
В JQuery и Angular также есть свои реализации этой функции.
Метод reduce(callback, initialValue) возвращает результат функции callback, которая применяется к каждому элементу массива.
Пример получения локального IP-адреса клиентской машины на Javascript с помощью HTML5 RTCPeerConnection API.
ScanFs — продвинутая утилита, предназначенная для быстрого поиска файлов и папок на диске с применением различных фильтров.