Javascript 限制函数和去抖动函数之间的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25991367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:10:44  来源:igfitidea点击:

Difference Between throttling and debouncing a function

javascript

提问by bhavya_w

Can anyone give me a in-simple-words explanation about the difference between throttling and debouncing a function for rate-limiting purposes.

任何人都可以给我一个简单的解释,说明出于速率限制目的的功能节流和去抖动之间的区别。

To me both seems to do the same the thing. I have checked these two blogs to find out :

对我来说,两者似乎都做同样的事情。我检查了这两个博客以找出:

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

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

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

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

回答by Donal

To put it in simple terms:

简单来说:

  • Throttlingwill delay executing a function. It will reduce the notifications of an event that fires multiple times.
  • Debouncingwill bunch a series of sequential calls to a function into a single call to that function. It ensures that one notification is made for an event that fires multiple times.
  • 节流将延迟执行功能。它将减少多次触发的事件的通知。
  • 去抖动会将一系列对函数的连续调用合并为对该函数的单个调用。它确保为多次触发的事件发出一个通知。

You can visually see the difference here

您可以在这里直观地看到差异

If you have a function that gets called a lot - for example when a resize or mouse move event occurs, it can be called a lot of times. If you don't want this behaviour, you can Throttleit so that the function is called at regular intervals. Debouncingwill mean it is called at the end (or start) of a bunch of events.

如果您有一个被多次调用的函数 - 例如,当发生调整大小或鼠标移动事件时,它可以被多次调用。如果你不希望这种行为,你可以油门它,这样的函数被调用定期。去抖动意味着它在一系列事件的结束(或开始)被调用。

回答by Dapeng Li

Personally I found debounceharder to comprehend than throttle.

我个人发现反跳更难理解比节流

As both functions help you postpone and reduce the rate of some execution. Assuming you are calling decorated functions returned by throttle/debounce repeatedly...

由于这两个功能都可以帮助您推迟和降低某些执行的速度。假设您正在重复调用由油门/去抖动返回的装饰函数......

  • Throttle: the original function be called at most once per specified period.
  • Debounce: the original function be called after the caller stops calling the decorated function after a specified period.
  • Throttle: 原函数每指定周期最多被调用一次。
  • Debounce调用者在指定时间后停止调用被修饰的函数后,原函数被调用。

I found the last part of debounce crucial to understand the goal it's trying to achieve. I also found an old version of the implementation of _.debounce helps the understanding (courtesy of https://davidwalsh.name/function-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);
  };
};

A far-fetched metaphor, but maybe could also help.

一个牵强的比喻,但也许也有帮助。

You have a friend named Chatty who likes to talk with you via IM. Assuming when she talks she sends a new message every 5 seconds, while your IM application icon is bouncing up and down, you can take the...

您有一位名叫 Chatty 的朋友喜欢通过 IM 与您交谈。假设当她说话时,她每 5 秒发送一条新消息,而您的 IM 应用程序图标则上下跳动,您可以采取...

  • Naiveapproach: check every message as long as it arrives. When your app icon bounces, check. It's not the most effective way, but you are always up-to-date.
  • Throttleapproach: you check once every 5 minutes (when there are new ones). When new message arrives, if you have checked anytime in the last 5 minutes, ignore it. You save your time with this approach, while still in the loop.
  • Debounceapproach: you know Chatty, she breaks down a whole story into pieces, sends them in one message after another. You wait until Chatty finishes the whole story: if she stops sending messages for 5 minutes, you would assume she has finished, now you check all.
  • 天真的方法:检查每条消息,只要它到达。当您的应用图标弹跳时,请检查。这不是最有效的方式,但您始终是最新的。
  • 节流方法:每 5 分钟检查一次(当有新的时)。当新消息到达时,如果您在过去 5 分钟内随时检查过,请忽略它。您可以使用这种方法节省时间,同时仍在循环中。
  • Debounce方法:您知道 Chatty,她将整个故事分解成多个部分,然后在一条又一条的消息中发送它们。您等到 Chatty 完成整个故事:如果她停止发送消息 5 分钟,您会认为她已完成,现在您检查所有内容。

回答by amit77309

Differences

差异

+--------------+-------------------+-------------------+
|              |  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    |
+--------------+-------------------+-------------------+

Explanation by use case:

用例说明

  • Search bar-Don't want to search every time user presses key? Want to search when user stopped typing for 1 sec. Use debounce1 sec on key press.

  • Shooting game-Pistol take 1 sec time between each shot but user click mouse multiple times. Use throttleon mouse click.

  • 搜索栏 -不想每次用户按键都搜索?想要在用户停止输入 1 秒时进行搜索。debounce在按键上使用1 秒。

  • 射击游戏 -手枪在每次射击之间需要 1 秒的时间,但用户多次点击鼠标。throttle在鼠标点击时使用。

Reversing their roles:

互换角色

  • Throttling 1 sec on search bar- If users types abcdefghijwith every character in 0.6 sec. Then throttle will trigger at first apress. It will will ignore every press for next 1 sec i.e. bat .6 sec will be ignored. Then cat 1.2 sec will again trigger, which resets the time again. So dwill be ignored and ewill get triggered.

  • Debouncing pistol for 1 sec-When user sees an enemy, he clicks mouse, but it will not shoot. He will click again several times in that sec but it will not shoot. He will see if it still has bullets, at that time (1 sec after last click) pistol will fire automatically.

  • 在搜索栏上限制 1 秒- 如果用户abcdefghij输入0.6 sec. 然后油门将在第一次a按下时触发。它将在接下来的 1 秒内忽略每次按下,即b在 0.6 秒时将被忽略。然后c在 1.2 秒将再次触发,再次重置时间。所以d将被忽略并被e触发。

  • 手枪弹跳1秒-当用户看到敌人时,他点击鼠标,但不会射击。他会在那秒内再次点击几次,但不会射击。他会看看它是否还有子弹,那个时候(最后一次点击后 1 秒)手枪会自动开火。

回答by Anshul

Throttlingenforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

节流会强制执行一个函数在一段时间内可以被调用的最大次数。如“最多每 100 毫秒执行一次此函数”。

Debouncingenforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."

去抖动强制一个函数在一段时间内不被调用之前不会被再次调用。如“仅当 100 毫秒过去了而没有被调用时才执行此函数”。

ref

参考

回答by Usman

Throttle (1 sec):Hello, I am a robot. As long as you keep pinging me, I will keep talking to you, but after exactly 1 second each. If you ping me for a reply before a second is elapsed, I will still reply to you at exactly 1 second interval. In other words, I just love to reply at exact intervals.

油门(1秒):你好,我是机器人。只要你一直给我打电话,我就会一直和你说话,但每次都刚好 1 秒。如果您在一秒过去之前ping我回复,我仍然会以1秒的间隔回复您。换句话说,我只是喜欢按确切的时间间隔回复。

Debounce (1 sec):Hi, I am that ^^ robot's cousin. As long as you keep pinging me, I am going to remain silent because I like to reply only after 1 second is passed since last time you pinged me. I don't know, if it is because I have an attitude problem or because I just don't like to interrupt people. In other words, if you keeping asking me for replies before 1 second is elapsed since your last invocation, you will never get a reply. Yeah yeah...go ahead! call me rude.

Debounce(1 秒):嗨,我是那个 ^^ 机器人的堂兄。只要你一直ping我,我就会保持沉默,因为我喜欢在你上次ping我1秒后才回复。我不知道,是因为我的态度有问题,还是因为我只是不喜欢打断别人。换句话说,如果您在上次调用后的 1 秒内一直要求我回复,您将永远不会得到回复。是啊是啊……加油!骂我粗鲁。



Throttle (10 min):I am a logging machine. I send system logs to our backend server, after a regular interval of 10 minutes.

油门(10 分钟):我是一台伐木机。在 10 分钟的固定间隔后,我将系统日志发送到我们的后端服务器。

Debounce (10 sec):Hi, I am not cousin of that logging machine. (Not every debounceris related to a throttlerin this imaginary world). I work as a waiter in a nearby restaurant. I should let you know that as long as you keep adding stuff to your order, I will not go to the kitchen for execution of your order. Only when 10 seconds have elapsed after you last modified your order, I will assume that you are done with your order. Only then will I execute your order in the kitchen.

Debounce(10 秒):嗨,我不是那台伐木机的堂兄。(并非每个去抖动器都与这个想象世界中的节流器有关)。我在附近的一家餐馆做服务员。我应该让你知道,只要你继续在你的订单中添加东西,我就不会去厨房执行你的订单。只有在您上次修改订单后 10 秒后,我才会认为您已完成订单。只有这样,我才会在厨房执行您的订单。



Cool Demos: https://css-tricks.com/debouncing-throttling-explained-examples/

酷演示:https: //css-tricks.com/debouncing-throttling-explained-examples/

Credits for the waiter analogy: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

服务员类比的积分:https: //codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf

回答by Ryan Taylor

It's simple.

这很简单。

They do the exact same thing(rate limiting) except while throttleis being called it'll fire your wrapped function periodically, and debouncewon't. Debounce just (tries to) call your function once at the very end.

它们做完全相同的事情(速率限制),除了在调用油门时,它会定期触发您的包装函数,而debounce则不会。Debounce 只是(尝试)在最后调用您的函数一次。

Example: If you're scrolling, throttle will slowly call your function while you scroll (every X milliseconds). Debounce will wait until after you're done scrolling to call your function.

示例:如果您正在滚动,则油门会在您滚动时缓慢调用您的函数(每 X 毫秒)。Debounce 将等到您完成滚动后调用您的函数。

回答by GibboK

Debouncingallows you to manage the frequency of calls that a function can receives. It combines multiple calls that happen on a given function so that repeated calls that occur before the expiration of a specific time duration are ignored. Basically debouncing ensures that exactly one signal is sent for an event that may be happening several times.

去抖动允许您管理函数可以接收的调用频率。它结合了在给定函数上发生的多个调用,以便忽略在特定持续时间到期之前发生的重复调用。基本上去抖动确保为可能发生多次的事件发送恰好一个信号。

Throttlingrestricts the frequency of calls that a function receives to a fixed time interval. It is used to ensuring that the target function is not invoked more often than the specified delay. Throttling is the reduction in rate of a repeating event.

节流将函数接收的调用频率限制在一个固定的时间间隔内。它用于确保目标函数的调用频率不会超过指定的延迟。节流是减少重复事件的速率。

回答by John Weisz

In layman's terms:

通俗地说:

Debouncingwill prevent a function from running whileit is still being called frequently. A debounced function will only run afterit has been determined that it is no longer being called, at which point it will run exactly once. Practical examples of debouncing:

反跳将防止功能运行,同时它仍然被频繁调用。去抖动函数只有确定不再被调用后才会运行,此时它只会运行一次。去抖动的实际例子:

  • Auto-saving or validating the contents of a text-field if the user "stopped typing": the operation will only be done once, AFTER it has been determined that the user is no longer typing (no longer pressing keys).

  • Logging where users rest their mouse: the user is no longer moving their mouse, so the (last) position can be logged.

  • 如果用户“停止打字”,则自动保存或验证文本字段的内容:在确定用户不再打字(不再按键)后,该操作只会执行一次。

  • 记录用户放置鼠标的位置:用户不再移动鼠标,因此可以记录(最后)位置。

Throttlingwill simply prevent a function from running if it has run recently, regardless of the call frequency. Practical examples of throttling:

如果函数最近运行过,则无论调用频率如何,节流都会阻止该函数运行。节流的实际例子:

  • Implementations of v-sync are based on throttling: the screen will only be drawn if 16ms elapsed since the last screen draw. No matter how many times the screen refresh functionality is called, it will only run at most once every 16ms.
  • v-sync 的实现基于节流:只有在上次屏幕绘制后 16 毫秒后才会绘制屏幕。无论屏幕刷新功能被调用多少次,它最多只会每 16ms 运行一次。

回答by Guy

A real-life analogy that personally helps me remember:

一个个人帮助我记住的现实生活类比:

  • debounce = a conversation. you wait for the other person to finish speaking before you reply.
  • throttle = a drum bit. you only play notes on a simple 4/4 drum bit.
  • 去抖动 = 对话。等对方说完再回复。
  • 油门=鼓位。你只在一个简单的 4/4 鼓位上演奏音符。

Use cases for debounce:

去抖动的用例:

  • Typing.You want to do something after the user stopped typing. So waiting 1sec after the last keystroke makes sense. Each keystroke restarts the wait.
  • Animation.You want to shrink back an element after the user stopped hovering over it. Not using debounce might cause an erratic animation as a result of the cursor unintentionally moving between the "hot" and "cold" zones.
  • 打字。你想在用户停止输入后做一些事情。所以在最后一次击键后等待 1 秒是有道理的。每次击键都会重新开始等待。
  • 动画片。你想在用户停止悬停在一个元素上后缩小它。由于光标在“热”和“冷”区域之间无意移动,不使用去抖动可能会导致动画不稳定。

Use cases for throttle:

油门的用例:

  • Scrolling.You want to react to scrolling but limit the amount of calculations made, so doing something every 100ms is enough to prevent potential lag.
  • Mouse move.Same as scrolling but for mouse move.
  • API callsYou want to fire an API call on certain UI events but want to limit the number of API calls you make not to overload your server.
  • 滚动。您想对滚动做出反应,但要限制进行的计算量,因此每 100 毫秒执行一次操作就足以防止潜在的延迟。
  • 鼠标移动。与滚动相同,但用于鼠标移动。
  • API 调用您想在某些 UI 事件上触发 API 调用,但又想限制您进行的 API 调用次数,以免服务器过载。

回答by Oleg Tsyba

throtleis just a wrapper around debouncewhich makes debounceto call passed functionin some period of time, if debouncedelays a function call on period of time which is bigger then specified in throtle.

throtle只是周围的包装去抖,这使得去抖调用通过function在一段时间内,如果去抖动延迟上的时间,这是更大然后在指定时间内的函数调用throtle