zoukankan      html  css  js  c++  java
  • debounce 与 throttle 区别

    原文地址:http://undefinedblog.com/debounce-and-throttle/

    二、什么是debounce                            

       1. 定义

      如果用手指一直按住一个弹簧,它将不会弹起直到你松手为止。

          也就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

    三、什么是throttle                              

       1. 定义

      如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。

      也就是会说预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

    在实现一些需要被频繁调用的函数时,我们通常都会使用 debounce 或 throttle方法。在我的印象中,它们的作用就是减少函数被调用的次数,但具体有什么区别,却真的不能说清楚。

    直到最近看了一篇精彩的博文,用可视化的方法展示了两者的区别,很有启发性,值得参考。

    注意到上图,第一行 Mousemove Events 展示了 mousemove 事件触发的频率。第二行和第三行是分别使用 underscore 与 jQuery 的 debounce 方法后事件的触发频率。第四、五行则是增加了一个 delay 参数后的触发频率。与之对比的是最后三行,使用的是 throttle 方法。

    首先我们的直观感觉是使用 debounce 方法相比于 throttle 方法事件触发的频率更低,但实际上不能这么理解。要解释上图的结果,首先需要了解 debounce 和 throttle 的原理。

    当我们阅读 lodash 的代码时会发现,throttle 方法不过是 debounce 方法的一个修饰。也就是说,_.throttle 和 _.debounce 最终都会都会调用 debounce 方法。那么 debounce 究竟是如何工作的呢?

    首先看 _.debounce 的 API:

    _.debounce(func, delay, options);  
    

    func 是需要被调用的目标函数,delay 是时间限制,options 是一系列的配置,为了简化问题,这里不多提。

    当调用 _.debounce 后,会返回一个函数,这个函数在被调用时会生成一个 setTimeout(delayed, delay)。其中 delayed 又是一个内部方法,在 delayed 被调用时进行如下检测:当前时间 - 上次func被调用事件 是否 小于 0 或 大于 delay ?如果是则执行一次 func,记录并返回执行结果,同时更新上次被调用时间;如果不是则调用 setTimeout 进行下一次的判断。

    因此,当你像下面这样绑定事件,

    $(window).on('mousemove', _.debounce(moveHandler, 500));
    

    并频繁移动鼠标时,你会发现 moveHandler 压根没有被调用过!直到你停下来后,moveHandler 才会被调用一次。

    至于 _.throttle 方法,只不过是多给 debounce 传了一个 maxWait 选项,这个选项的意思是至少保证在每 maxWait 时间让 func 被调用一次。

    说到这儿,你应该就明白了为什么会出现上图那样的调用情况。如果你频繁的移动鼠标,throttle 会保证在每 maxWait 时间调用 func 一次,而 debounce 如果没有明确设置 maxWait,是一直不会调用 func 直到你停止移动鼠标后才会调用一次。

    因此,可以笼统的说 _.throttle 就是设置了 leading=true, trailing=true 及 maxWait 的 _.debounce。

    那什么时候该用 debounce 什么时候该用 throttle 呢?

    下面我列举了一些场景:

    • input 中输入文字自动发送 ajax 请求进行自动补全: debounce
    • resize window 重新计算样式或布局:debounce
    • scroll 时更新样式,如随动效果:throttle

    最重要的还是理解两者对调用时间及次数上的处理,根据业务逻辑选择最合适的优化方案!

  • 相关阅读:
    微信二维码 场景二维码 用于推送事件,关注等 注册用户 ,经过测试
    简单的 Helper 封装 -- CookieHelper
    简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
    Java反射机制
    Windows Azure Web Site (13) Azure Web Site备份
    Windows Azure Virtual Machine (1) IaaS用户手册
    Windows Azure Web Site (1) 用户手册
    Windows Azure Web Site (12) Azure Web Site配置文件
    Windows Azure Web Site (11) 使用源代码管理器管理Azure Web Site
    Windows Azure Web Site (10) Web Site测试环境
  • 原文地址:https://www.cnblogs.com/alphafly/p/5578148.html
Copyright © 2011-2022 走看看