节流和去抖函数之间的区别

时间:2014-09-23 09:19:54

标签: javascript

任何人都可以给我一个简单的单词解释,说明限制和去除功能之间的区别是为了限速目的。

对我来说,两者似乎都做同样的事情。我已经检查过这两个博客了解:

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

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

18 个答案:

答案 0 :(得分:204)

简单来说:

  • 限制会延迟执行某项功能。它将减少多次触发事件的通知。
  • Debouncing 会将对函数的一系列顺序调用捆绑到对该函数的单个调用中。它确保为多次触发的事件发出一个通知。

您可以直观地看到差异here

如果你有一个被调用的函数 - 例如当调整大小或鼠标移动事件时,它可以被调用很多次。如果您不想要这种行为,可以节流它,以便定期调用该函数。 Debouncing 意味着它会在一系列事件的结尾(或开始)被调用。

答案 1 :(得分:97)

我个人认为 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);
  };
};

一个牵强附会的比喻,但也许也可以帮助。

你有一个名叫Chatty的朋友喜欢通过IM与你交谈。假设她说话时她每隔5秒发送一条新消息,当你的IM应用程序图标上下弹跳时,你就可以拿走......

  • 天真方法:只要到达时检查每条消息。当您的应用图标反弹时,请检查。这不是最有效的方式,但你总是最新的。
  • 节流方法:每5分钟检查一次(当有新的时候)。当新消息到达时,如果您在过去5分钟内随时检查过,请忽略它。使用这种方法可以节省您的时间,同时仍处于循环中。
  • 去抖方法:你知道Chatty,她将整个故事分解成碎片,然后一个接一个地发送它们。你等到Chatty完成整个故事:如果她停止发送消息5分钟,你会认为她已经完成,现在你检查所有。

答案 2 :(得分:35)

用例说明:

搜索栏-?是否不想每次用户按下键都进行搜索?想要在用户停止键入1秒钟时进行搜索。按下debounce 1秒。

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

角色互换

在搜索栏上节流1秒-如果用户在10秒钟内键入“长文本...”,则它应调用搜索大约10次。按下第一个键“ L”时,将调用第一个搜索。

手枪弹跳1秒钟-:当用户看到敌人时,他单击鼠标,但不会射击。他将在该秒内再次单击几次,但不会射击。他会查看它是否仍有子弹,这时(最后一次单击后1秒钟)手枪会自动射击。

编辑:

差异

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

答案 3 :(得分:22)

限制强制执行函数随时间调用的最大次数。如“每100毫秒最多执行一次此功能一样。”

Debouncing 强制执行一个函数,直到经过一定时间而没有调用它时才会再次调用它。如“只有在没有被调用的情况下经过100毫秒才执行此函数。”

ref

答案 4 :(得分:16)

油门(1秒):您好,我是机器人。只要您一直对我执行ping操作,我就会一直与您交谈,但是每次恰好在1秒钟之后。如果您在不到一秒钟的时间内向我ping回复,我仍然会每隔1秒钟回复一次。换句话说,我只是喜欢按固定的间隔回复。

防抖(1秒):嗨,我是^^机器人的表亲。只要您继续对我执行ping操作,我将保持沉默,因为我只希望在1秒过去之后自动回复。我不知道是因为我有态度问题还是因为我不想打扰别人。换句话说,如果自上次调用以来一直在1秒钟之前要求我答复,那么您将永远不会得到答复。是的...继续前进!叫我粗鲁。


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

防抖动(10秒):嗨,我不是该日志记录仪的表亲。 (在这个虚构的世界中,并非每个 debouncer 都与一个 thromler 相关)。我在附近的一家餐馆当服务生。我应该告诉您,只要您继续向订单中添加商品,我就不会去厨房执行订单。在您上次修改订单后仅10秒钟之后,我将假定您已完成订单。只有这样,我才能在厨房执行您的订单。


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

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

答案 5 :(得分:15)

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

限制将功能接收的呼叫频率限制为固定的时间间隔。它用于确保不会比指定的延迟更频繁地调用目标函数。限制是重复事件发生率的降低。

答案 6 :(得分:9)

外行人的说法:

Debouncing 会阻止某个功能运行,而仍会频繁调用它。去抖动函数只会在确定不再被调用后运行,此时它将只运行一次。去抖动的实际例子:

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

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

限制只会阻止某个功能在最近运行时运行,无论呼叫频率如何。节流的实际例子:

  • v-sync的实现基于限制:仅在自上次屏幕绘制后经过16ms时才会绘制屏幕。无论调用屏幕刷新功能多少次,它每16ms最多只能运行一次。

答案 7 :(得分:8)

很简单。

它们执行完全相同的操作(速率限制),只是在调用油门时会定期触发您的功能,并反跳惯于。刚结束时反跳(尝试)一次调用您的函数。

示例:如果您正在滚动,那么在滚动时,油门将缓慢地调用您的函数(每X毫秒)。防弹跳将一直等到滚动完成后再调用函数。

答案 8 :(得分:6)

节流

限制执行可调用函数的最大次数 随着时间的推移。如“执行此功能最多每100次执行一次 毫秒。”说在正常情况下,您会称其为 在10秒钟内功能1,000次。如果仅将其调节一次 每100毫秒,最多只能执行该功能100 次

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

反跳

去抖强制执行一个函数,直到出现 经过一定的时间没有被调用。如 “仅在没有功能的情况下经过100毫秒才执行此功能 被呼叫。”

也许一个函数被快速调用了1,000次,分散了3秒钟,然后停止调用。如果您在100毫秒处将其反跳,则一旦爆发结束,该功能将仅在3.1秒时触发一次。每次在猝发过程中调用该函数时,都会重置反跳计时器

来源:-throttle and debouncing

答案 9 :(得分:4)

假设我们有一个在事件“ E”上调用的回调函数“ cb”。 让“ E”在1秒内被触发1000次,因此将有1000次调用“ cb”。就是1个通话/毫秒。要进行优化,我们可以使用:

  • 限制:如果限制为(100ms),则“ cb”为 在[第100毫秒,第200毫秒,300毫秒,...第1000毫秒]上调用。即1个通话/ 100毫秒。 将“ cb”的1000个呼叫优化为10个呼叫。
  • 反跳:反跳时间为(100ms)时,“ cb”在[1100th秒]只会被调用一次。这是最后一次触发“ E”(在第1000毫秒)后100毫秒。 将“ cb”的1000个呼叫优化为1个呼叫。

答案 10 :(得分:2)

lodash图书馆建议使用以下文章https://css-tricks.com/debouncing-throttling-explained-examples/,其中详细解释了DebounceThrottle之间的区别及其来源

答案 11 :(得分:2)

throtle 只是 debounce 的包装,它会使去抖在某段时间内调用传递<div class="block right"> <img src="http://via.placeholder.com/300x300" /> <h2>Header 2.1</h2> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> </div>,如果< strong> debounce 延迟函数调用的时间段,该时间段大于 throtle 中指定的时间。

答案 12 :(得分:2)

防弹跳使得该函数只能在自上次调用后的一定时间后才能执行

increase()

油门模式限制了随时间推移可调用给定事件处理程序的最大次数。它使处理程序可以按指定的时间间隔定期调用,而忽略在此等待时间结束之前发生的每个调用。

o.increase(newSize)

答案 13 :(得分:1)

据我了解,简单来说 节流-类似于调用setInterval(callback)一定次数,即在事件发生时随时间推移调用同一函数一定次数  和.. 防弹跳-类似于在事件发生后经过一定时间后调用setTImeout(callbackForApi)或调用函数。 此链接可能有帮助- https://css-tricks.com/the-difference-between-throttling-and-debouncing/

答案 14 :(得分:1)

有关典型用例的示例,我建议使用@Guy的答案。但是,让我理解这两个概念的最佳方法是制作披萨。 ?

假设您是一位了不起的披萨制造商,因此您商店中的顾客不断要求更多披萨。

限制: 您决定只在每个小时结束时才放一个披萨,只要您在该小时内至少收到一个披萨请求即可。

您在一小时内收到100份披萨请求,因此您在该小时结束时提供了一份披萨。然后,您不会在下一个小时收到披萨的要求,因此您不会放出披萨。然后,您在下一个小时收到10个披萨请求,因此您在该小时结束时发出了一个披萨。

反跳: 您会因为客户不断要求披萨而感到烦恼,因此您决定只在他们停止询问您一整分钟后才给他们披萨。

他们连续30分钟要比萨饼,但之后又停止询问一分钟。到那时,您将给他们一个披萨。

然后,他们连续5分钟要比萨饼,此后一分钟便不再要求。此时,您再给他们一个披萨。

答案 15 :(得分:1)

一个现实的类比,可以帮助我记住:

  • 防抖=对话。您等待对方说完话再回复。
  • 油门=鼓位。您只能在简单的4/4鼓头上演奏音符。

去抖动的用例:

  • 键入。。您想在用户停止键入后执行一些操作。因此,在最后一次按键后等待1秒是有意义的。每次击键都会重新开始等待。
  • 动画。。您要在用户停止将鼠标悬停在元素上之后将其收缩。不使用反跳可能会由于光标无意间在“热”和“冷”区域之间移动而导致动画不稳定。

油门的用例

  • 滚动。您想对滚动做出反应,但要限制计算量,因此每100毫秒执行一次操作足以防止潜在的滞后。
  • 鼠标移动。与滚动相同,但用于鼠标移动。
  • API调用。您想在某些UI事件上触发API调用,但想限制不使服务器超载的API调用次数。

答案 16 :(得分:0)

本文对此进行了很好的解释,并且还具有图形。

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

摘自文章(并作了一些澄清):

(节流)和去抖之间的主要区别在于,节流可确保至少每X毫秒定期执行一次功能。

通常在指定时间结束时反跳功能调用该函数,而当第一次调用该功能时,则进行油门调用。有时,防抖动可能需要额外的配置,该配置会对此进行更改以在开始时进行调用。当使用特定配置调用时,一些反跳实现实际上可以起到节流阀的作用(请参阅Lodash源代码)。

答案 17 :(得分:0)

这实际上是限制事件的方式。例如,如果您正在监听 onclick 事件,如果它是常规的,它将监听您的每次点击。

如果你使用 Throttle,它会设置你想要监听事件的时间间隔,例如每秒监听一次点击。

Debounce 是一种限制性更强的方法,它只会在事件的开始或结束时触发自身。比如你在滚动并且你使用了Debounce,它只会在你开始滚动和完成滚动时触发。