来源:http://blog.coding.net/blog/the-difference-between-throttle-and-debounce-in-underscorejs

Unserscore.js文档:http://www.bootcss.com/p/underscore/

github:https://github.com/jashkenas/underscore

在这里只讲了Unserscore.js其中的2个函数debounce throttle

debounce throttle使用场景

只要牵涉到连续事件或频率控制相关的应用都可以考虑到这两个函数,比如:

  • 游戏射击,keydown 事件
  • 文本输入、自动完成,keyup 事件
  • 鼠标移动,mousemove 事件
  • DOM 元素动态定位,window 对象的 resize 和 scroll 事件

前两者 debounce 和 throttle 都可以按需使用;后两者肯定是用 throttle 了。如果不做过滤处理,每秒种甚至会触发数十次相应的事件。尤其是 mousemove 事件,每移动一像素都可能触发一次事件。如果是在一个画布上做一个鼠标相关的应用,过滤事件处理是必须的,否则肯定会造成糟糕的体验。

Underscore.js是一个很精干的库,压缩后只有5.2KB。它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程。

本文仅探讨Underscore.js的两个函数方法 _.throttle_.debounce 的原理、效果和用途。

通常的函数(或方法)调用过程分为三个部分:请求、执行和响应。(文中“请求”与“调用”同义,“响应”与“返回”同义,为了更好的表述,刻意采用请求和响应的说法。)

某些场景下,比如响应鼠标移动或者窗口大小调整的事件,触发频率比较高。若稍处理函数微复杂,需要较多的运算执行时间,响应速度跟不上触发频率,往往会出现延迟,导致假死或者卡顿感。

在运算资源不够的时候,最直观的解决办法就是升级硬件,诚然通过购买更好的硬件可以解决部分问题,但是也需要为此付出高额的成本。特别是客户端和服务器模式,要求客户端统一升级硬件基本不可能。

在资源有限的前提下,处理函数无法即时响应高频调用。退而求其次,只响应部分请求是否可行呢?某些场景下的密集性请求,具备很强的同质和连续性。比如说,鼠标移动的轨迹参数。响应越及时效果越平滑,但是如果响应速度跟不上时,反而会出现卡顿感,如果适当的丢弃一些请求效果更流畅。

throttledebounce 是解决请求和响应速度不匹配问题的两个方案。二者的差异在于选择不同的策略。

电梯超时

想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应。假设电梯有两种运行策略 throttledebounce ,超时设定为15秒,不考虑容量限制。

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

使用示例

_.throttle 使用示例

function log( event ) {
console.log( $(window).scrollTop(), event.timeStamp );
}; // 控制台记录窗口滚动事件,触发频率比你想象的要快
$(window).scroll( log ); // 控制台记录窗口滚动事件,每250ms最多触发一次
$(window).scroll( _.throttle( log, 250 ) );

_.debounce 使用示例

function ajax_lookup( event ) {
// 对输入的内容$(this).val()执行 Ajax 查询
}; // 字符输入的频率比你预想的要快,Ajax 请求来不及回复。
$('input:text').keyup( ajax_lookup ); // 当用户停顿250毫秒以后才开始查找
$('input:text').keyup( _.debounce( ajax_lookup, 250 ) );

可视化演示

示例中每一行都以30ms的速度绘制时间轴,第一行Mousemove Events是参考基准,以50ms每次的响应频率,在时间轴上输出循环可见ASCII码字符。

当鼠标进入左侧方型区域(mouseenter 事件)所有行开始绘制时间轴, 鼠标晃动(mousemove 事件)会在时间轴上绘制字符块,每个字符块表示事件被触发一次。为了展现延迟触发效果,相邻字符块的演示和文字是不同的。

顶部的两个按钮每100毫秒触发1次每200毫秒触发2次演示以固定频率匀速触发事件的效果。

浅谈 Unserscore.js 中 _.throttle 和 _.debounce 的差异的更多相关文章

  1. 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

    Underscore.js是一个很精干的库,压缩后只有5.2KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程. 本文仅探讨Underscore.js的两个 ...

  2. 【第三周读书笔记】浅谈node.js中的异步回调和用js-xlsx操作Excel表格

    在初步学习了node.js之后,我发现他的时序问题我一直都很模糊不清,所以我专门学习了一下这一块. 首先我们来形象地理解一下进程和线程: 进程:CPU执行任务的模块.线程:模块中的最小单元. 例如:c ...

  3. 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异[转]

    看的文章来自: https://blog.coding.net/blog/the-difference-between-throttle-and-debounce-in-underscorejs 使用 ...

  4. 浅谈Vue.js

    作为一名Vue.js的忠实用户,我想有必要写点文章来歌颂这一门美好的语言了,我给它的总体评价是“简单却不失优雅,小巧而不乏大匠”,下面将围绕这句话给大家介绍Vue.js,希望能够激发你对Vue.js的 ...

  5. 浅谈C++11中的多线程(三)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 浅谈C++11中的多线程(一) - 唯有自己强大 - 博客园 (cnblogs.c ...

  6. 浅谈C++11中的多线程(二)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 浅谈C++11中的多线程(一) - 唯有自己强大 - 博客园 (cnblogs.c ...

  7. 转: 浅谈C/C++中的指针和数组(二)

    转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...

  8. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  9. 转载 浅谈C/C++中的static和extern关键字

    浅谈C/C++中的static和extern关键字 2011-04-21 16:57 海子 博客园 字号:T | T   static是C++中常用的修饰符,它被用来控制变量的存贮方式和可见性.ext ...

随机推荐

  1. Navicat premium连接Oracle报ORA-28547错误

    1:ORA-28547 原因:navicate Primium版本的OCi和本地数据库的OCI版本不一致. 解决方法: 1:把navicate Primium版本自带oci.dll替换本地Oracle ...

  2. mybatis源码阅读-MappedStatement各个属性解析过程(八)

    调用方 类org.apache.ibatis.builder.xml.XMLMapperBuilder private void configurationElement(XNode context) ...

  3. UVa - 12661 - Funny Car Racing

    先上题目: 12661 Funny Car RacingThere is a funny car racing in a city with n junctions and m directed ro ...

  4. Clojure:通过ZeroMQ推送消息

    通过ZeroMQ的pub/sub模式,我们可以实现发送推送消息的功能.以下为示例代码(入门可参考此文:http://www.cnblogs.com/ilovewindy/p/3984269.html) ...

  5. springmvc 时间返回格式化

    如果是@ResponseBody,可以通过@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")设置返回的样式: 如果是不是@ResponseBody ...

  6. 每一个程序猿必知之SEO

    似乎由于受这篇文章的影响 http://katemats.com/what-every-programmer-should-know-about-seo/ 于是我也觉得我应该写一个每一个程序猿必知之S ...

  7. ios 视频播放代码Demo

    方法一: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. / ...

  8. POJ 2421--Constructing Roads【水题 && 最小生成树 && kruskal】

    Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 20889   Accepted: 88 ...

  9. HTML如何让IMG自动适应DIV容器大小

    版权声明:本文为博主原创文章,未经博主允许不得转载.作者:沙师弟专栏 https://blog.csdn.net/u014597198/article/details/80403946HTML如何让I ...

  10. 1D1D动态规划优化

    1D1D动态规划优化 1D/1D 动态规划优化初步所谓1D/1D 动态规划,指的是状态数为O(n),每一个状态决策量为O(n)的动态规划方程.直接求解的时间复杂度为O(n2),但是,绝大多数这样的方程 ...