Skip to content

Comments

Исправляет функцию debounce()#5493

Open
loonlylokly wants to merge 5 commits intodoka-guide:mainfrom
loonlylokly:fix-debounce
Open

Исправляет функцию debounce()#5493
loonlylokly wants to merge 5 commits intodoka-guide:mainfrom
loonlylokly:fix-debounce

Conversation

@loonlylokly
Copy link
Contributor

@loonlylokly loonlylokly commented Aug 18, 2024

Описание

Переписал функцию debounce() на более простой вариант без проверки времени и переделал описание работы.
Вот пример проблемы с которой столкнулся: https://jsbin.com/ceqetosabi/2/edit?js,console

Чек-лист

  • Текст оформлен согласно руководству по стилю
  • Ссылки на внутренние материалы начинаются со слеша и заканчиваются слэшем либо якорем на заголовок (/css/color/, /tools/json/, /tools/gulp/#kak-ponyat)
  • Ссылки на картинки, видео и демки относительные (images/example.png, demos/example/, ../demos/example/)

@loonlylokly loonlylokly changed the title Исправляет функцию debounce Исправляет функцию debounce() Aug 18, 2024
@github-actions github-actions bot added js Контент по JavaScript статья Расширенный материал labels Aug 18, 2024
@TatianaFokina TatianaFokina added the улучшение Доработка существующего label Aug 18, 2024
@loonlylokly
Copy link
Contributor Author

@vitya-ne Что скажешь по тексту объяснения? Норм?

@vitya-ne
Copy link
Contributor

@vitya-ne Что скажешь по тексту объяснения? Норм?

чтобы callback функция передаваемая в setTimeout не потеряла контекст его нужно привязать с помощью apply. Это важно при работе с обработчиком событий браузера.

По смыслу все верно, но есть, как мне кажется, неточности )

  • не то что бы функция callback может потерять контекст, она его может не получить. по-моему это не совсем тоже самое.
  • используя .apply() мы не привязываем контекст (для этого есть .bind()), а устанавливаем его при вызове.
  • может стоит категоричное 'нужно' поменять на 'можно' ? .call() ведь тоже тут справится.
  • Это важно при работе с обработчиком событий браузера я бы заменил на Это важно если обработчик события обращается кthis`.


Отметим несколько важных моментов:

- возвращаемая функция `perform` НЕ должна быть стрелочной, чтобы не терялся контекст;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давайте тут уточним:

  • возвращаемая функция perform НЕ должна быть стрелочной, чтобы не терялся контекст callback функции;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется это не очень хорошая рекомендация. Я бы постаралась избегать неявных this bindings.
Я предположу что здесь проблема в том что this теряет контекст кликнутого элемента. Для таких случаев я бы просто использовала currentTarget. Для классов - стрелочную функцию метод

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

С другой стороны хуже от этого не будет. Давайте так: если вы хотите сохранить контекст колбек-метода не используйте стрелочную функцию для perform. Мелкое различие которое не так сильно заостряет на этом внимание )

Отметим несколько важных моментов:

- возвращаемая функция `perform` НЕ должна быть стрелочной, чтобы не терялся контекст;
- чтобы `callback` функция, передаваемая в `setTimeout`, не потеряла контекст, его нужно привязать с помощью `apply`. Это важно при работе с обработчиком событий браузера.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давайте тут тоже уточним:

  • чтобы callback функция, передаваемая в setTimeout, получила контекст, укажем его с помощью apply. Это важно при использовании debounce для обработчиков событий браузера.

@skorobaeus
Copy link
Member

@HellSquirrel приди, функции погляди!


Отметим несколько важных моментов:

- возвращаемая функция `perform` НЕ должна быть стрелочной, чтобы не терялся контекст;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется это не очень хорошая рекомендация. Я бы постаралась избегать неявных this bindings.
Я предположу что здесь проблема в том что this теряет контекст кликнутого элемента. Для таких случаев я бы просто использовала currentTarget. Для классов - стрелочную функцию метод


1. При вызове функции `perform`, сначала выполняется `clearTimeout(timer)`. Так удаляется ранее установленный таймер, если он существует. Это необходимо, чтобы предотвратить выполнение предыдущего вызова функции `callback`, если новый вызов произошёл до завершения задержки.
1. Устанавливается новый таймер с помощью `setTimeout`, и ссылка на этот таймер сохраняется в переменной `timer`.
1. В `setTimeout` первым аргументом передаётся стрелочная функция с вызовом нашего `callback` c привязкой контектса и передачей всех аргументов. Вторым аргументом передаётся задержка `delay`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. В `setTimeout` первым аргументом передаётся стрелочная функция с вызовом нашего `callback` c привязкой контектса и передачей всех аргументов. Вторым аргументом передаётся задержка `delay`.
1. В `setTimeout` первым аргументом передаётся стрелочная функция с вызовом нашего `callback` c привязкой контекста и передачей всех аргументов. Вторым аргументом передаётся задержка `delay`.

Обратите внимание, что API функции не поменялось. Мы как передавали [`event`](/js/event/), так и передаём. То есть для внешнего мира debounced-функция ведёт себя точно так же, как и простая функция-обработчик.

Это удобно, потому что меняется лишь одна небольшая часть программы, не затрагивая системы в целом.
Обратите внимание, что API функции не поменялось. Мы как передавали [`event`](/js/event/), так и передаём. То есть для внешнего мира debounced-функция ведёт себя точно так же, как и простая функция-обработчик. Это удобно, потому что меняется лишь одна небольшая часть программы, не затрагивая системы в целом.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кстати api поменялось. Синхронная функция - обработчик могла возвращать значение, debounce версия этого делать не может

она нужна, чтобы результат поиска помещался в окошко
@github-actions
Copy link

Превью контента из 6524345 опубликовано.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

js Контент по JavaScript статья Расширенный материал улучшение Доработка существующего

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants