Как стать автором
Обновить

Разбор debounce() в lodash

Функция debounce - это обёртка над вашей функцией, которая позволяет отменить и отложить на какое-то время её повторные вызовы разными способами.

Простой, но частоиспользующийся пример

Рассмотрим следующий код React приложения:

import { debounce } from "lodash";
import React, { useRef } from "react";

const HomePage = () => {
  const counter = useRef(1);

  const handleClick = debounce(
    (count) => {
      console.log("click happened!", count);
    },
  );

  return (
    <button
      onClick={() => {
        counter.current += 1;
        handleClick(counter.current); // Вызов функции №1
        handleClick(counter.current); // Вызов функции №2
        handleClick(counter.current); // Вызов функции №3
      }}
    >
      Click me
    </button>
  );
};

export default HomePage;

Здесь используется "записывающая" способность рефов в React. Если вы не знакомы с ней, прошу сначала прочитать официальную документацию.

Обёртка, в которую мы обернули нашу функцию отклоняет 2-ой и 3-ий вызов функции при клике на кнопку. А точнее она запоминает последний (3-ий) и затем выполняет его.


Зачастую в React приложении идёт многоповторный перерендеринг из-за частых изменений со стороны пользователя. Чтобы не нагружать систему, мы можем воспользоваться данной функцией. Чаще всего она может пригодиться в ситуации, когда пользователь вводит в input какое-либо содержимое и происходит ререндер при вводе каждого символа. Так как нам это не нужно, мы можем отложить его на n-ое количество времени.

Параметры функции

debounce(func, [time], [options])

func - функция, которую необходимо обернуть
time - время в миллисекундах до следующего вызова
options - набор дополнительных параметров в виде объекта

[options.leading] (boolean, false по-умолчанию) - если true, то разрешает запуск функции моментально, не дожидаясь выставленного в параметре time времени. Последующие вызовы будут отклоняться до тех пор пока не пройдёт заданное время. По истечению будет запущен последний вызов функции.

[options.maxWait] (number) - максимальное время которое функция не будет вызываться при её многократном вызове. Дело в том, что если функция будет вызываться чаще, заданного времени в параметре time, то таймер будет каждый раз сбрасываться и наша функция не будет выполнена до тех пор, пока на протяжении n времени её не будут трогать. Если мы задаём этот параметр, то когда истечёт заданное в нём время, функция будет принудительно вызвана.

[options.trailing] (boolean, true по-умолчанию) - противоположность leading.
Если задан как true, то разрешает запуск функции по прошествии заданного в параметре time времени. Если false, то соответственно запрещает.

Если мы одновременно зададим  { leading: true, trailing: true }, то у нас из одного вызова функции получится сразу два. Первый будет сразу, а второй по прошествии заданного времени.

Если всё ещё не понятно, то рекомендую запустить локально данный пример с разными настройками данной функции

  const handleClick = debounce(
    (count) => {
      console.log("click happened!", count);
    },
    3000,
    { leading: true, maxWait: 3500, trailing: true }
  );

Методы функции

Помимо параметров, данная функция имеет 2 метода:

cancel() - отменяет отложенный вызов до его запуска
flush() - наоборот, запускает отложенный вызов раньше времени

Добавим 2 элемента к предыдущему коду:

<button
  onClick={() => {
    handleClick.cancel();
  }}
  >
  Cancel
</button>

<button
  onClick={() => {
    handleClick.flush();
   }}
  >
  Call immediately
</button>

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.