underscore.js提供了很多很有用的函数,今天想说说其中的两个。这两个函数都用于限制函数的执行。

debounce

在解释这个函数前,我们先从一个例子看下这个函数的使用场景。假设我们网站有个搜索框,用户输入文本我们会自动联想匹配出一些结果供用户选择。我们可能首先想到的做法就是监听keypress事件,然后异步去查询结果。这个方法本身是没错的,但是如果用户快速的输入了一连串的字符,假设是10个字符,那么就会在瞬间触发了10次的请求,这无疑不是我们想要的。我们想要的是用户停止输入的时候才去触发查询的请求,这时候函数防抖可以帮到我们。

函数防抖就是让某个函数在上一次执行后,满足等待某个时间内不再触发此函数后再执行,而在这个等待时间内再次触发此函数,等待时间会重新计算。

我们先看下underscore.js里相关函数的定义:

_.debounce(function, wait, [immediate])

 
// 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, args, context, timestamp, result; var later = function() {
var last = _.now() - timestamp; if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
if (!timeout) context = args = null;
}
}
}; return function() {
context = this;
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
} return result;
};
};
简单版,自己实现
function debounce(fn,time){
var isRun = false;
function later(){
fn();
isRun = false;
}
return function(){
if(!isRun){
isRun = true
setTimeout(later,time);
}
}}

参数function是需要进行函数防抖的函数;参数wait则是需要等待的时间,单位为毫秒;immediate参数如果为true,则debounce函数会在调用时立刻执行一次function,而不需要等到wait这个时间后,例如防止点击提交按钮时的多次点击就可以使用这个参数。

所以,上面那个场景,我们可以这么解决:

function query() {
//进行异步调用查询
} var lazyQuery = _.debounce(query, 300);
$('#search').keypress(lazyQuery);

throttle

我们网站经常会有这样的需求,就是滚动浏览器滚动条的时候,更新页面上的某些布局内容或者去调用后台的某接口查询内容。同样的,如果不对函数调用的频率加以限制的话,那么可能我们滚动一次滚动条就会产生N次的调用了。但是这次的情况跟上面的有所不同,我们不是要在每完成等待某个时间后去执行某函数,而是要每间隔某个时间去执行某函数,避免函数的过多执行,这个方式就叫函数节流

同样的,我们看下underscore.js里相关函数的定义:

_.throttle(function, wait, [options])

// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_.throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};

简单版,自己实现。

function throttle(fn,time){
var id ;
return function(){
if(id) clearTimeout(id);
id=setTimeout(fn,time);
}
}

参数function是需要进行函数节流的函数;参数wait则是函数执行的时间间隔,单位是毫秒。option有两个选项,throttle第一次调用时默认会立刻执行一次function,如果传入{leading: false},则第一次调用时不执行function。{trailing: false}参数则表示禁止最后那一次延迟的调用。具体可以看源码进行理解。

所以,在滚动滚动条的场景,我们可以这么做:

function handleScroll() {
//进行滚动时的相关处理
} var throttled = _.throttle(handleScroll, 100);
$(window).scroll(throttled);

参考

http://underscorejs.org/#debounce
http://underscorejs.org/#throttle

可参考:https://css-tricks.com/the-difference-between-throttling-and-debouncing/

【原文】https://segmentfault.com/a/1190000002764479

节流throttle和防抖debounce的更多相关文章

  1. JavaScript 高级系列之节流 [throttle] 与防抖 [debounce]

    一.概念 这两个东西都是为了项目优化而出现的,官方是没有具体定义的,他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等问题:像这类事件一般像 scroll keyup ...

  2. 函数节流throttle和防抖debounce

    throttle 函数节流 不论触发函数多少次,函数只在设定条件到达时调用第一次函数设定,函数节流 1234567891011 let throttle = function(fn,intervalT ...

  3. [JavaScript] 函数节流(throttle)和函数防抖(debounce)

    js 的函数节流(throttle)和函数防抖(debounce)概述 函数防抖(debounce) 一个事件频繁触发,但是我们不想让他触发的这么频繁,于是我们就设置一个定时器让这个事件在 xxx 秒 ...

  4. “浅入浅出”函数防抖(debounce)与节流(throttle)

    函数防抖与节流是日常开发中经常用到的技巧,也是前端面试中的常客,但是发现自己工作一年多了,要么直接复用已有的代码或工具,要么抄袭<JS高级程序设计>书中所述"函数节流" ...

  5. 防抖debounce和节流throttle

    大纲 一.出现缘由 二.什么是防抖debounce和节流throttle 三.应用场景 3.1防抖 3.2节流 一.出现缘由 前端开发中,有一部分用户行为会频繁触发事件,而对于DOM操作,资源加载等耗 ...

  6. js 函数的防抖(debounce)与节流(throttle)

    原文:函数防抖和节流: 序言: 我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove, resize, onscroll等等,有些时候,我们并不能或者不想频 ...

  7. js 函数的防抖(debounce)与节流(throttle) 带 插件完整解析版 [helpers.js]

    前言:         本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽.         函数防抖与节流是做什么的?下面进行通俗的讲解. 本文借鉴:h ...

  8. Java版的防抖(debounce)和节流(throttle)

    概念 防抖(debounce) 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定时间到来之前,又触发了事件,就重新开始延时. 防抖,即如果短时间内大量触发同一事件,都会 ...

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

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

随机推荐

  1. 移植Cocos2D到Android平台的原理

    幸运的,SpriteBuilder使得适配(安卓)多种多样的屏幕尺寸变得容易起来,因为Android Xcode插件允许你使用任何Cocos2D的特性并且可以继续使用很多iOS的框架(framewor ...

  2. java工具类(二)之java正则表达式表单验证

    java正则表达式表单验证类工具类(验证邮箱.手机号码.qq号码等) 这篇文章主要介绍了java使用正则表达式进行表单验证工具类,可以验证邮箱.手机号码.qq号码等方法,需要的朋友可以参考下. jav ...

  3. LeetCode之“树”:Sum Root to Leaf Numbers

    题目链接 题目要求: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represe ...

  4. 2010-01-20 12:09 ubuntu下minicom的安装及使用

    转http://hi.baidu.com/npugtawqdnbgqrq/item/106f805409b42813db163527 ubuntu下minicom的安装及使用 安装: sudo apt ...

  5. 如何设置静态IP

    首先在CMD命令行ipconfig查看临时分配的IP地址: 然后打开我的"网络"--->"本地连接"--->IPv4--->属性 电信DNS劫 ...

  6. 面试之路(27)-链表中倒数第K个结点

    代码的鲁棒性: 所谓的鲁棒性是指能够判断输入是否合乎规范,能对不和规范的程序进行处理. 容错性是鲁棒性的一个重要体现. 防御性编程有助于提高鲁棒性. 切入正题,我可不是标题党: 链表倒数第k个节点 列 ...

  7. linux下64位汇编的系统调用(2)

    知道了syscall调用号之后还不算完,还要搞清楚2件事: 1 每种调用号需要传递哪些参数: 2 调用如何传递参数以及结果如何返回: 第一个问题的答案是: 在linux系统中某个程序执行时进行的系统调 ...

  8. listview中的adapter学习小结

    概述 Adapter是数据和UI之间的一个桥梁,在listview,gridview等控件中都会使用到,android给我们提拱了4个adapte供我们使用: BaseAdapter是一个抽象类,继承 ...

  9. svn 不能添加.a文件

    1.打开终端输入    open ~/.subversion/ 2.双击打开config文件 3.修改如下两行 # global-ignores = *.o *.lo *.la *.al .libs ...

  10. wamp 服务监控和启动

    近日我的 wamp 莫名其妙的崩溃重启,apache 能自动起来, mysql 却悲剧了. 于是有了下面的wamp服务监控和启动的批处理文件 @echo off rem define loop tim ...