原文地址: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

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

debounce 与 throttle 区别的更多相关文章

  1. debounce与throttle区别

    在2011年,Twitter网站曾爆出一个问题:在主页往下滚动时,页面会变得缓慢以致没有响应.John Resig发表了一篇文章< a blog post about the problem&g ...

  2. 试议常用Javascript 类库中 throttle 与 debounce 辅助函数的区别

    问题的引出 看过我前面两篇博客的童鞋可能会注意到都谈到了事件处理的优化问题. 在很多应用中,我们需要控制函数执行的频率, 例如 窗口的 resize,窗口的 scroll 等操作,事件触发的频率非常高 ...

  3. 白话debounce和throttle

    遇到的问题 在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如: 鼠标事件:mousemove(拖曳)/mouseover(划过)/mouseWhe ...

  4. Debounce 和 Throttle 的原理及实现---防止频繁触发某事件

    原文:http://blog.csdn.net/redtopic/article/details/69396722 在处理诸如 resize.scroll.mousemove 和 keydown/ke ...

  5. 防抖(Debounce)与节流( throttle)区别

    http://www.cnblogs.com/ShadowLoki/p/3712048.html http://blog.csdn.net/tina_ttl/article/details/51830 ...

  6. 函数防抖与函数节流 封装好的debounce和throttle函数

    /** * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行 * * @param {function} func 传入函数,最后一个参数是额外增加的this对象,. ...

  7. underscore里面的debounce与throttle

    throttle 策略的电梯.保证如果电梯第一个人进来后,15秒后准时运送一次,不等待.如果没有人,则待机. debounce 策略的电梯.如果电梯里有人进来,等待15秒.如果又人进来,15秒等待重新 ...

  8. debounce、throttle、requestAnimationFrame

    今天review同事代码,代码实现了返回顶部的功能,用到了lodash库中的throttle,我看着眼生,于是乎去看了下lodash文档,然后牵出了debounce,具体的知识点,这里不再赘述,底部的 ...

  9. debounce还是throttle(去抖和节流)

    debounce 去抖 我的理解很简单,比方说window.onscroll会疯狂触发handler,此时给它一个debounce(handler, delayTime). 就是不管你延时时间内触发了 ...

随机推荐

  1. c语言中 *p++ 和 (*p)++ 和 *(p++) 和 *(++p) 和++(*p)和 *(p--)和 *(--p)有什么区别?

    *p++是指下一个地址; (*p)++是指将*p所指的数据的值加一; /******************解释**********************/ ->C编译器认为*和++是同优先级 ...

  2. Python3爬虫(六) 解析库的使用之Beautiful Soup

    Infi-chu: http://www.cnblogs.com/Infi-chu/ Beautiful Soup 借助网页的结构和属性等特性来解析网页,这样就可以省去复杂的正则表达式的编写. Bea ...

  3. TensorFlow深层神经网络常用方法

    深度学习所示深层神经网络的代名词,重要特性:多层.非线性. 若只通过线性变换,任意层的神经网络模型与单层神经网络模型的表达能力没有任何区别,这是线性模型的局限性.对于线性可分的问题中,线性模型可解决, ...

  4. 关于xampp 集成开发包电脑重启mysql无法启动的问题

    关于xampp 集成开发包电脑重启mysql无法启动的问题. 在做php开发时,安装过xampp,也不知道是版本老了还是什么问题,总是出现当天晚上下班关机,第二天上班mysql不能启动,在网上查找些资 ...

  5. linux进程 生产者消费者

    #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> # ...

  6. Django学习之天气调查实例(3):部署静态文件CSS、JS、images等(部署环境基于Ubuntu)

    在设计登录界面时,采用了网上下载的登录模板,漂亮,简易.但是在测试和部署时,发现原来模板中采用的js文件和css文件,却着实让我折腾了好几天. 在以往的网页设计中,一般只要把测试站点开启后,网页中的静 ...

  7. Python的re模块的常用方法

    一.re的match与search方法 1.re.match方法 re.match 尝试从字符串的起始位置匹配一个模式,匹配成功re.match方法返回一个匹配的对象,如果不是起始位置匹配成功的话,m ...

  8. 【原创】java 获取十个工作日之前或之后的日期(算当天)-完美解决-费元星

    [原创]java 获取十个工作日之后的日期(算当天)-完美解决-费元星(仅考虑星期六星期天) /** * * 根据开始日期 ,需要的工作日天数 ,计算工作截止日期,并返回截止日期 * @param s ...

  9. 序列化---fastjson使用

    该文章主要介绍com.alibaba.fastjson的使用. 首先创建maven工程,导入fastjson.挑个热度高的版本就好了. 首先考虑下,我们通常什么时候会使用序列化和反序列化: 1.将ja ...

  10. APP功能性测试-3

    定义:兼容测试就是指软件在特定的硬件平台,不同的应用软件之间,不同的操作系统平台上,不同的网络等环境中是否能够正常的运行的测试  (会不会产生不兼容) 兼容性测试的作用 进一步提高产品质量 和其他软件 ...