debounce与throttle

lodash的方法里,有两个比较有趣的方法:debouncethrottle,这两个方法是用来限制连续事件的触发频率的。具体的使用请查看官方文档

debounce: 防抖

1
2
3
4
5
_.debounce(func, [wait=0], [options={
leading: false,
maxWait: Number,
trailing: true
}])

作用:连续触发的事件,如果一直在触发,没有中途暂停且暂停时间超过wait,那么这些事件会合并为一次,直到暂停时间超过wait时执行。然后判断下一轮…直到事件最后一次触发。
使用:
debounce()接受一些配置参数,返回一个 new debounced function,这个对象拥有cancelflush方法,这两个方法都不咋用,就看看配置参数就行了。
默认的效果图:
debounce默认效果图
使用leading属性的效果图:
debounce使用leading属性的效果图
所以,当设置leading:true, trailing: false时会在wait时间段的开始触发合并后的事件。

注意:leading: true,trailing: true时同默认情况
自己尝试一下,鼠标在trigger area上不停的动:


See the Pen Debounce. Leading by Corbacho (@dcorb) on CodePen.



还有一个maxWait属性,请查看区别这一部分。
注意:

1
2
3
4
5
6
7
// WRONG
$(window).on('scroll', function() {
_.debounce(doSomething, 300);
});

// RIGHT
$(window).on('scroll', _.debounce(doSomething, 200));

使用场景:

  • scrollresize输入验证这种连续触发的事件,触发时运行某些代码,大多数时候你可能不需要每次事件都要运行这些代码。比如input输入时验证
  • 有个新增弹框,为了防止快速点击两次确定按钮提交两次接口,可以使用debounce

throttle:节流

1
2
3
4
_.throttle(func, [wait=0], [options={
leading: true,
trailing: true
}])

作用:连续触发的事件,如果一直在触发,不论有没有中途暂停,wait时间段里的事件会被合并为一次。
使用:
参数少了个maxWait,其他的不论是参数还是返回值和debounce都一样。
自己尝试一下,无限滚动:


See the Pen Infinite scrolling throttled by Corbacho (@dcorb) on CodePen.



使用场景:

  • scroll无限滚动翻页,此时不能用debounce,因为一直连续触发,只要你没有中间暂停时间超过wait,那你滚动的那么多事件都会合并为一次。此时用throttle,连续触发的事件在每wait事件内触发的多次会合并为一次,还是可以连续触发,只不过频率降低了

区别

这两个方法非常相似,都降低了触发频率,只有一点细微的差别:
throttle方法其实是加了maxWait选项的debounce方法,lodash的源码中就可以看到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function throttle(func, wait, options) {
var leading = true,
trailing = true;

if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
'leading': leading,
'maxWait': wait,
'trailing': trailing
});
}

结语:
大神David Corbacho说建议直接使用lodashunderscore的这两个方法。这里放下源码的地址:debounce,利用的是setTimeout方法实现这种效果。

堂 wechat
欢迎关注我的微信公众号,里面有各种小故事哦!
坚持原创技术分享,您的支持将鼓励我继续创作!