Разница между регулированием и ослаблением функции

251

Может ли кто-нибудь дать мне объяснение в простых словах о разнице между регулированием и отменой функции в целях ограничения скорости.

Мне кажется, что оба делают одно и то же. Я проверил эти два блога, чтобы узнать:

http://remysharp.com/2010/07/21/throttling-function-calls

http://benalman.com/projects/jquery-throttle-debounce-plugin/

bhavya_w
источник
102
demo.nimius.net/debounce_throttle - хорошая визуализация
три
4
@ thriqon, что визуализация лучше, чем мое описание.
Донал
Да, это помогло мне понять и эту концепцию ... +1 для оригинального автора ;-)
thriqon
Очень простой пример, который помог мне понять. jsfiddle.net/Voronar/sxjy25ew/1
Кирилл А. Халитов
1
Здесь также можно увидеть визуализацию codepen.io/chriscoyier/pen/vOZNQV
trungk18

Ответы:

346

Проще говоря:

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

Вы можете увидеть разницу здесь

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

Донал
источник
9
Я думаю, что ссылка на визуализацию Thriqon показывает, как она работает очень хорошо. Если у вас есть функция, которая часто вызывается - например, когда происходит событие изменения размера или перемещения мыши, ее можно вызывать много раз. Если вы не хотите этого, вы можете регулировать его, чтобы функция вызывалась через равные промежутки времени. Дебусинг будет означать, что он вызывается в конце (или в начале) группы вызовов.
Донал
10
@AdamM. Посмотрите на визуализацию здесь: demo.nimius.net/debounce_throttle
Донал
2
@AdamM. Нет. Вы можете визуализировать это, перемещая мышь в демоверсии и останавливая движение мыши время от времени. Панель отказов будет «тикать» после того, как вы остановили все движения мыши, в то время как панель дросселя будет «тикать», пока мышь движется, но с пониженной (удушенной) скоростью.
Джон Вайс
26
Я абсолютно не люблю визуализацию. Спасибо!
Сэмми
4
Ссылка более ценная, чем тысяча слов
Finesse
148

Лично я нашел дребезг труднее осмыслить , чем дроссель .

Поскольку обе функции помогут вам отложить и снизить скорость выполнения некоторых. Предполагая, что вы вызываете декорированные функции, возвращаемые throttle / debounce несколько раз ...

  • Дроссель : исходная функция вызывается не более одного раза за указанный период.
  • Debounce : исходная функция вызывается после того, как вызывающая сторона перестает вызывать декорированную функцию после определенного периода .

Я обнаружил, что последняя часть обсуждения важна для понимания цели, которую он пытается достичь. Я также нашел, что старая версия реализации _.debounce помогает пониманию (любезно предоставлено https://davidwalsh.name/function-debounce ).

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

Надуманная метафора, но, возможно, также может помочь.

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

  • Наивный подход: проверяйте каждое сообщение по мере его поступления. Когда значок вашего приложения подпрыгивает, проверьте. Это не самый эффективный способ, но вы всегда в курсе.
  • Подход газа : вы проверяете один раз каждые 5 минут (когда появляются новые). Когда приходит новое сообщение, если вы проверили в любое время за последние 5 минут, игнорируйте его. С этим подходом вы экономите свое время, оставаясь в курсе событий.
  • Подход « Дебад» : вы знаете, Чэтти, она разбивает целую историю на части, отправляет их в одном сообщении за другим Вы ждете, пока Чэтти закончит всю историю: если она перестанет отправлять сообщения на 5 минут, вы предположите, что она закончила, теперь вы проверяете все.
Дапенг Ли
источник
17
Не понял разницу между этими двумя функциями, пока я не прочитал это. Спасибо
Симус Барретт
7
Метафора - один из величайших примеров, которые я когда-либо читал о газе и дебатах. Спасибо.
Виньеш
96

Различия

+--------------+-------------------+-------------------+
|              |  Throttle 1 sec   |  Debounce 1 sec   |
+--------------+-------------------+-------------------+
| Delay        | no delay          | 1 sec delay       |
|              |                   |                   |
| Emits new if | last was emitted  | there is no input |
|              | before 1 sec      |  in last 1 sec    |
+--------------+-------------------+-------------------+

Пояснение к случаю использования :

  • Панель поиска - Не хотите искать каждый раз, когда пользователь нажимает клавишу? Хотите искать, когда пользователь перестал печатать на 1 сек. Используйте debounce1 секунду при нажатии клавиши.

  • Стрельба игры - Пистолет занимает 1 секунду между выстрелами, но пользователь нажимает кнопку мыши несколько раз. Используйте throttleпо щелчку мыши.

Поменять свои роли :

  • Регулирование 1 сек на панели поиска - если пользователи вводят abcdefghijкаждый символ 0.6 sec. Тогда дроссель сработает при первом aнажатии. Он будет игнорировать каждое нажатие в течение следующих 1 секунды, т.е. bпри 0,6 секунды будет игнорироваться. Затем cчерез 1,2 сек снова сработает триггер, который снова сбрасывает время. Так dбудет игнорироваться и eбудет срабатывать.

  • Сбрасывание пистолета на 1 сек. Когда пользователь видит врага, он щелкает мышью, но он не стреляет. Он будет нажимать снова несколько раз в течение этой секунды, но он не будет стрелять. Он увидит, есть ли в нем пули, в это время (через 1 секунду после последнего щелчка) пистолет автоматически выстрелит.

amit77309
источник
37

Регулирование обеспечивает максимальное количество раз, которое функция может быть вызвана в течение долгого времени. Как в «выполнять эту функцию не чаще, чем раз в 100 миллисекунд».

Дебюксинг гарантирует, что функция не будет вызываться снова, пока определенное количество времени не пройдет без ее вызова . Как в «выполнить эту функцию, только если прошло 100 миллисекунд без ее вызова».

ссылка

Anshul
источник
20

Дроссель (1 сек): Здравствуйте, я робот. Пока ты будешь пинговать меня, я буду говорить с тобой, но ровно через 1 секунду. Если вы пингуете мне ответ до истечения секунды, я все равно отвечу вам ровно через 1 секунду. Другими словами, я просто люблю отвечать через определенные промежутки времени.

Дебод (1 секунда): Привет, я кузен этого робота ^^. Пока вы продолжаете пинговать меня, я буду молчать, потому что мне нравится отвечать только через 1 секунду после того, как вы в последний раз пинговали меня . Я не знаю, потому что у меня проблемы с отношением или я просто не люблю перебивать людей. Другими словами, если вы продолжаете запрашивать у меня ответы до истечения 1 секунды с момента вашего последнего вызова, вы никогда не получите ответ. Да, да ... давай! называй меня грубым


Дроссель (10 мин): я лесозаготовительная машина. Системные журналы отправляются на наш серверный сервер через 10 минут.

Дебад (10 секунд): Привет, я не двоюродный брат этой машины. (Не каждый дебоузер связан с троттлером в этом воображаемом мире). Я работаю официантом в соседнем ресторане. Я должен сообщить вам, что пока вы продолжаете добавлять вещи в свой заказ, я не пойду на кухню для исполнения вашего заказа. Только через 10 секунд после того, как вы в последний раз изменили свой заказ, я буду считать, что вы сделали свой заказ. Только тогда я выполню ваш заказ на кухне.


Классные демонстрации: https://css-tricks.com/debouncing-throttling-explained-examples/

Кредиты по аналогии с официантами: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

Усман
источник
1
лучшее объяснение.
Каран Шарма
17

Debouncing позволяет вам управлять частотой вызовов, которые может получать функция. Он объединяет несколько вызовов, которые происходят с данной функцией, так что повторные вызовы, которые происходят до истечения определенного времени, игнорируются. По сути, устранение неполадок гарантирует, что ровно один сигнал отправляется для события, которое может происходить несколько раз.

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

GibboK
источник
17

Это просто.

Они делают то же самое (ограничение скорости) за исключением того, что во время вызова дросселя он будет периодически запускать вашу упакованную функцию, а debounce не будет. Debounce просто (пытается) вызвать вашу функцию один раз в самом конце.

Пример : при прокрутке газ будет медленно вызывать вашу функцию во время прокрутки (каждые X миллисекунд). Debounce будет ждать до тех пор, пока вы не закончите прокрутку, чтобы вызвать вашу функцию.

Райан Тейлор
источник
Стоит отметить, что в этих демонстрациях они могут не выглядеть «идентичными», потому что debounce всегда будет запускать X миллисекунд после последнего события, в то время как последний вызов throttle может произойти раньше (и его не нужно вызывать снова, когда обычно запускается debounce ). это довольно несущественно, но стоит упомянуть, если вы посмотрите на демонстрации.
Райан Тейлор
16

С точки зрения непрофессионала:

Деблокирование предотвратит запуск функции во время ее частого вызова . Отклоненная функция будет запущена только после того, как будет определено, что она больше не вызывается, после чего она будет запущена ровно один раз. Практические примеры разоблачения:

  • Автоматическое сохранение или проверка содержимого текстового поля, если пользователь «прекратил печатать»: операция будет выполнена только один раз, ПОСЛЕ того, как было определено, что пользователь больше не печатает (больше не нажимает клавиши).

  • Запись в журнал, где пользователи покоят свою мышь: пользователь больше не перемещает свою мышь, поэтому (последняя) позиция может быть зарегистрирована.

Регулирование просто предотвратит запуск функции, если она выполнялась недавно, независимо от частоты вызовов. Практические примеры дросселирования:

  • Реализации v-sync основаны на регулировании: экран будет отрисован, только если прошло 16 мс с момента последнего отрисовки экрана. Независимо от того, сколько раз вызывается функция обновления экрана, она будет запускаться максимум раз в 16 мс.
Джон Вайс
источник
7

Реальная аналогия, которая лично помогает мне вспомнить:

  • debounce = разговор . Вы ждете, пока другой человек закончит говорить, прежде чем ответить.
  • дроссель = бит барабана . Вы играете ноты только на простом 4/4 барабане.

Варианты использования для debounce :

  • Typing. Вы хотите что-то сделать после того, как пользователь перестал печатать. Так что ожидание 1сек после последнего нажатия клавиши имеет смысл. Каждое нажатие клавиши возобновляет ожидание.
  • Анимация. Вы хотите уменьшить элемент после того, как пользователь перестал на него висеть. Неиспользование debounce может привести к ошибочной анимации из-за непреднамеренного перемещения курсора между «горячей» и «холодной» зонами.

Варианты использования для газа :

  • Скроллинг. Вы хотите отреагировать на прокрутку, но ограничить объем вычислений, поэтому достаточно делать каждые 100 мсек, чтобы предотвратить потенциальную задержку.
  • Мышь двигается. То же, что прокрутка, но для перемещения мыши.
  • Вызовы API Вы хотите инициировать вызов API для определенных событий пользовательского интерфейса, но хотите ограничить количество вызовов API, которые вы делаете, чтобы не перегружать ваш сервер.
парень
источник
4

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

Олег Цыба
источник
2

Дроссельный

Регулирование обеспечивает максимальное количество раз, когда функция может быть вызвана сверхурочно. Как в «выполнять эту функцию не чаще, чем раз в 100 миллисекунд». Скажем, в нормальных условиях вы бы вызывали эту функцию 1000 раз за 10 секунд. Если вы дросселируете его только один раз за 100 миллисекунд, он будет выполнять эту функцию не более 100 раз.

(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls

дребезга

Дебюксинг гарантирует, что функция не будет вызываться снова, пока определенное количество времени не пройдет без ее вызова. Как в «выполнить эту функцию, только если прошло 100 миллисекунд без ее вызова».

Возможно, функция вызывается 1000 раз в быстрой посылке, рассеивается в течение 3 секунд, а затем перестает вызываться. Если вы отменили его за 100 миллисекунд, функция сработает только один раз, за ​​3,1 секунды после окончания пакета. Каждый раз, когда функция вызывается во время пакета, она сбрасывает таймер устранения неполадок.

источник: - газ и глушение

bajran
источник
2

Предположим, у нас есть функция обратного вызова "cb", которая будет вызвана для события "E". Пусть «Е» сработает 1000 раз за 1 секунду, следовательно, будет 1000 обращений к «cb». Это 1 вызов / мс. Для оптимизации мы можем использовать:

  • Регулирование : при регулировании (100 мс) вызывается «cb» [100-я мс, 200-я мс, 300-я мс, ... 1000-я мс]. Это 1 звонок / 100 мс.Здесь 1000 звонков на «кб» оптимизированы до 10 звонков.
  • Debouncing : с debouncing (100ms), «cb» будет вызываться только один раз в [1100th sec]. Это 100 мс после последнего запуска «Е», который произошел на [1000-й мс]. Здесь 1000 звонков на «кб» оптимизированы до 1 звонка.
Nat Geo
источник
1

Насколько я понимаю, в простых терминах Throttling - аналогично вызову setInterval (callback) определенное количество раз, то есть вызову одной и той же функции определенное количество раз в течение времени при возникновении события и ... Debouncing - аналогично вызову setTImeout (callbackForApi) или вызов функции по истечении определенного времени после возникновения события. Эта ссылка может быть полезной - https://css-tricks.com/the-difference-between-throttling-and-debouncing/

Праная Бинью
источник