По мере того, как я узнаю, как создавать новые функции в Javascript, мне нравится придерживаться общепринятой практики построения, заставляя все работать, а затем возвращаться к рефакторингу. Оптимизируя свой код, я всегда думал, что лучший способ приблизиться к этому - посмотреть, как я пишу javascript и как он влияет на такие вещи, как нотация Big O Notation. Однако часто забываемая форма рефакторинга и оптимизации заключается в том, чтобы снять часть нагрузки с вашего браузера. Введите debounce.

Debounce - это функция javascript, которая ограничивает количество раз, когда функция может запускаться последовательно прослушивателем событий. Типичная функция debounce выглядит так (пока не обращайте внимания на цифры):

1.      function debounce(func, wait, immediate) {
          var timeout;
2.      return function() {
          var context = this;
          var args = arguments;
3.      var later = function() {
          timeout = null;
       if (!immediate) func.apply(context, args);
       };
4.      var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
       if (callNow) func.apply(context, args);
       };
    };

Я пронумеровал разделы этой функции, чтобы объяснить, что здесь происходит.

В 1 мы инициализируем нашу функцию противодействия и устанавливаем переменную, называемую таймаутом. Эти аргументы нам понадобятся, когда мы инициализируем дебаунс:

  • func - функция, на которую позже будет ссылаться анонимная функция в 2
  • wait - в миллисекундах, как долго функция должна ждать перед повторным запуском.
  • немедленно - это показывает, что функция сработает немедленно, но затем дождется

В 2 мы видим, что debounce возвращает анонимную функцию. Здесь мы устанавливаем переменные, которые будут использоваться в нашем setTimeout позже.

В 3 мы создаем функцию, вызываемую позже, которая вызывается только в том случае, если экземпляр нашего противодействия уже был запущен с немедленным запуском. Строка func.apply позволяет нам вызывать нашу исходную функцию, но с нашим контекстом и аргументами, определенными с помощью this и наших аргументов.

В 4 у нас много чего происходит. Первое, что мы делаем, сохраняем переменную callNow, чтобы проверить, следует ли запускать функцию. Следующее, что делает наш код, это очищает тайм-аут, который на данном этапе кода равен нулю. После сброса нашего тайм-аута мы переназначаем нашу переменную тайм-аута на setTimeout (позже, подождите). Последняя строка проверяет, выполняются ли условия callNow, а затем вызывает исходную функцию, как и ранее, с func.apply.

TL; DR: при первой инициализации этого противодействия будет установлено время ожидания в зависимости от установленной длительности ожидания в миллисекундах. Когда этот тайм-аут истечет, функция снова сможет сработать. А пока он сработает только один раз.

Реализация в реальном мире

Теперь, когда мы взглянули на то, что происходит в нашей функции debounce, давайте посмотрим, как заставить ее работать внутри нашего кода.

Реализация противодействия довольно проста. После того, как вы создали свой противодействие, все, что вам действительно нужно сделать, это прикрепить его к прослушивателю событий.

Перед дебаундом:

window.addEventListener('click', myFunction)

После устранения проблемы:

window.addEventListener('click', debounce(myFunction), 500)

Все, что нам нужно было сделать, это обернуть myFunction в нашу функцию противодействия. Кроме того, это также хорошее место для установки времени ожидания. Здесь мы установили 1000 миллисекунд. Это означает, что мы ограничены одним событием клика каждую 1 секунду, независимо от того, сколько раз мы нажимали.

Отныне Debounce полностью входит в мои проекты. Это действительно может немного снизить нагрузку на наши браузеры, что, как мы надеемся, приведет к улучшению общего пользовательского опыта.