JS魔法堂:函数节流(throttle)与函数去抖(debounce)

}, idle)

}

}

复制代码

三、什么是throttle

1. 定义

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

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

接口定义:

复制代码

/**

  • 频率控制 返回函数连续调用时,action 执行频率限定为 次 / delay

  • @param delay {number} 延迟时间,单位毫秒

  • @param action {function} 请求关联函数,实际应用需要调用的函数

  • @return {function} 返回客户调用函数

*/

throttle(delay,action)

复制代码

2. 简单实现

复制代码

var throttle = function(delay, action){

var last = 0return function(){

var curr = +new Date()

if (curr - last > delay){

action.apply(this, arguments)

last = curr

}

}

}

复制代码

四、underscore v1.7.0相关的源码剖析

1. _.throttle函数

复制代码

_.throttle = function(func, wait, options) {

/* options的默认值

  • 表示首次调用返回值方法时,会马上调用func;否则仅会记录当前时刻,当第二次调用的时间间隔超过wait时,才调用func。

  • options.leading = true;

  • 表示当调用方法时,未到达wait指定的时间间隔,则启动计时器延迟调用func函数,若后续在既未达到wait指定的时间间隔和func函数又未被调用的情况下调用返回值方法,则被调用请求将被丢弃。

  • options.trailing = true;

  • 注意:当options.trailing = false时,效果与上面的简单实现效果相同

*/

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;

// 当到达wait指定的时间间隔,则调用func函数

// 精彩之处:按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,但这里还考虑到假如客户端修改了系统时间则马上执行func函数。

if (remaining <= 0 || remaining > wait) {

// 由于setTimeout存在最小时间精度问题,因此会存在到达wait的时间间隔,但之前设置的setTimeout操作还没被执行,因此为保险起见,这里先清理setTimeout操作

if (timeout) {

clearTimeout(timeout);

timeout = null;

}

previous = now;

result = func.apply(context, args);

if (!timeout) context = args = null;

} else if (!timeout && options.trailing !== false) {

// options.trailing=true时,延时执行func函数

timeout = setTimeout(later, remaining);

}

return result;

};

};

复制代码

按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,至于remaining > wait的作用是什么,我现在也不太清楚。

精彩之处:按理来说remaining <= 0已经足够证明已经到达wait的时间间隔,但这里还考虑到假如客户端修改了系统时间则马上执行func函数。这里谢谢@GreatFeng的提示!

2. _.debounce函数

复制代码

_.debounce = function(func, wait, immediate) {

// immediate默认为false

var timeout, args, context, timestamp, result;

var later = function() {

// 当wait指定的时间间隔期间多次调用_.debounce返回的函数,则会不断更新timestamp的值,导致last < wait && last >= 0一直为true,从而不断启动新的计时器延时执行func

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;

}

结尾

正式学习前端大概 3 年多了,很早就想整理这个书单了,因为常常会有朋友问,前端该如何学习,学习前端该看哪些书,我就讲讲我学习的道路中看的一些书,虽然整理的书不多,但是每一本都是那种看一本就秒不绝口的感觉。

以下大部分是我看过的,或者说身边的人推荐的书籍,每一本我都有些相关的推荐语,如果你有看到更好的书欢迎推荐呀。

ate) {

result = func.apply(context, args);

if (!timeout) context = args = null;

}

结尾

正式学习前端大概 3 年多了,很早就想整理这个书单了,因为常常会有朋友问,前端该如何学习,学习前端该看哪些书,我就讲讲我学习的道路中看的一些书,虽然整理的书不多,但是每一本都是那种看一本就秒不绝口的感觉。

以下大部分是我看过的,或者说身边的人推荐的书籍,每一本我都有些相关的推荐语,如果你有看到更好的书欢迎推荐呀。

前端学习书籍导图-1

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值