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

Javascript 函数的节流和去抖动之间的区别,javascript,Javascript,有人能给我一个简单的解释,说明为了限制速率而对函数进行节流和去抖动的区别吗 对我来说,两人似乎都在做同样的事情。我查看了这两个博客以了解: 简单地说: 节流将延迟功能的执行。它将减少多次触发的事件的通知 去抖动将一系列对函数的顺序调用组合成对该函数的单个调用。它确保为多次触发的事件发出一个通知 您可以直观地看到差异 如果有一个函数被多次调用,例如,当发生调整大小或鼠标移动事件时,可以多次调用该函数。如果不希望出现这种行为,可以对其进行限制以便定期调用该函数去抖动意味着在一系列事件结束(或开

有人能给我一个简单的解释,说明为了限制速率而对函数进行节流和去抖动的区别吗

对我来说,两人似乎都在做同样的事情。我查看了这两个博客以了解:


简单地说:

  • 节流将延迟功能的执行。它将减少多次触发的事件的通知
  • 去抖动将一系列对函数的顺序调用组合成对该函数的单个调用。它确保为多次触发的事件发出一个通知
您可以直观地看到差异


如果有一个函数被多次调用,例如,当发生调整大小或鼠标移动事件时,可以多次调用该函数。如果不希望出现这种行为,可以对其进行限制以便定期调用该函数去抖动意味着在一系列事件结束(或开始)时调用它。

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


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

我个人认为去盎司节流更难理解

因为这两个函数都可以帮助您推迟和降低某些执行的速度。假设您正在反复调用throttle/debounce返回的修饰函数

  • 节流阀:每个指定周期最多调用一次原始函数
  • Debounce:调用方在指定时间段后停止调用修饰函数后,将调用原始函数
我发现debounce的最后一部分对于理解它试图实现的目标至关重要。我还发现一个旧版本的u.debounce实现有助于理解(由提供)

这是一个牵强的比喻,但或许也能有所帮助

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

  • 天真的方法:只要消息到达,就检查它。当你的应用程序图标反弹时,请检查。这不是最有效的方法,但你总是最新的
  • 节流方式:每5分钟检查一次(当有新的节流方式时)。当新消息到达时,如果您在过去5分钟内的任何时候检查过,请忽略它。这种方法可以在循环中节省时间
  • Debounce方法:你知道,Chatty,她把整个故事分解成几个部分,一个接一个地发送信息。你一直等到Chatty完成整个故事:如果她停止发送消息5分钟,你会认为她已经完成了,现在你检查所有
    • 用外行的话说:


      去抖动将阻止函数在仍然频繁调用时运行。取消公告的函数只有在确定不再调用它之后才会运行,此时它将只运行一次。去抖动的实际示例:

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

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


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

      • v-sync的实现是基于节流的:只有在上次屏幕绘制后16毫秒后才会绘制屏幕。无论屏幕刷新功能被调用多少次,它最多每16ms运行一次

      lodash库建议使用以下文章详细解释
      去盎司
      节流
      之间的区别及其起源

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


      去Bouncing强制函数在经过一定时间后不再被调用。如“仅当100毫秒过去而未调用时才执行此函数。”


      throtle只是去盎司的一个包装,它使得去盎司在一段时间内调用传递的
      函数
      ,如果去抖动延迟函数调用的时间段大于throtle中指定的时间段

      差异

      +--------------+-------------------+-------------------+
      |              |  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秒时搜索。使用
        debounce
        1 按一下键

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

      颠倒角色

      • +--------------+-------------------+-------------------+
        |              |  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    |
        +--------------+-------------------+-------------------+
        
        (10s * 1,000) = 10,000ms
        10,000ms / 100ms throttling = 100 maximum calls
        
        function debounce(func,wait){
          let timeout
          return(...arg) =>{
            clearTimeout(timeout);
            timeout= setTimeout(()=>func.apply(this,arg),wait)
          }
        }
        
        
        function SayHello(){
          console.log("Jesus is saying hello!!")
        }
        
        
        let x = debounce(SayHello,3000)
        x()
        
        function throttle(callback, interval) {
          let enableCall = true;
        
          return (...args)=> {
            if (!enableCall) return;
        
            enableCall = false;
            callback.apply(this, args);
            setTimeout(() => enableCall = true, interval);
          }
        }
        
        
        function helloFromThrottle(){
          console.log("Jesus is saying hi!!!")
        }
        
        const foo = throttle(helloFromThrottle,5000)
        foo()