2.节流方案

我心飞翔 分类:javascript

目录——思维导图

image.png

一.学习方法

我学习知识点的流程有以下几个阶段(仅供参考):

graph LR
获取阶段  --> 理解阶段   -->  纠错扩展阶段 --> 实战阶段 --> 回归总结阶段

每个阶段详情如下:

获取阶段 理解阶段 纠错扩展阶段 实战阶段 回归总结阶段
简化内容 作用 是否错误 维度 总结
快速获取 原理 深度扩展 实践 感悟
多渠道收集 实现 广度扩展

二.方案简介

节流(throttle)
顾名思义:有节制的流出

和防抖不同,防抖是重置,节流是保持一定的间隔触发。

定义:如果你持续触发事件,每隔一段时间,只执行一次事件

形象记忆:水滴按照相同的时间间隔滴落下来,不管水分子在内部快速慢速运动

需求场景: 滑动事件按照相同的时间间隔触发,现在是滑动就+1

image.png

三.理解阶段

实现代码如下:

    function throttle(fn, delay) {
        let timer;
        return () => {
            let that = this;
            let arg = arguments;
            if (!timer) {
                timer=setTimeout(() => {
                    fn.apply(that, arg)
                    timer = null
                }, delay)
            };
        }
    }
 

throttle2.gif

我们仔细观察会发现两个特征:

1.事件是在N秒后执行的

2.在移除鼠标的时候,在N秒后还会执行最后一次

那么有特征的地方就会有需求,需求如下:

  1. 是否可以控制立即执行

2.是否可以控制最后一次执行还是不执行

    /*第二代版本
options
leading:false 表示禁用第一次执行
trailing: false 表示禁用停止触发的回调
*/
function throttle(fn, delay, options) {
let timer,
that = this,
args = arguments,
result,
previous = 0;
if (!options) {
options = { leading: true, trailing: true };
}
result = function () {
let _now = new Date().getTime();
let remaining = delay - (_now - previous);  
//计算时间差、配置leading:true 开启首次触发事件立即执行函数
if (
(remaining <= 0 || remaining > delay) &&
options.leading !== false
){
if (timer) {
clearTimeout(timer);
timer = null;
}
//上面使用clearTimeout是为了保证在下面立即执行的fn函数之前不在有之前创建的定时器去执行fn方法
//(防止定时器执行+立即执行导致同一时间多次执行的问题)
previous = _now;
return fn.apply(that, args);
}
if (!timer && options.trailing !== false) {
//记录创建的定时器
timer = setTimeout(function () {
//为什么timer要放在setTimeout内重置为null?
//由于if根据timer判断是否创建定时器,从而控制定时器的创建次数以便实现真正的节流
//简答讲只有本次定时器执行了,才可以timer = null创建下一次的定时器...以此...类推...
timer = null;
previous = new Date().getTime();//记录最近一次触发fn事件的时间
return fn.apply(that, args); //到时间执行事件处理函数
}, wait);
}
}
return   result;
}

e6bbb1ddb70a0b04cdd7032ef061f2db.webp

四.应用阶段

以后有高级的应用在持续更新....

文档:5.throttle.html
链接:note.youdao.com/noteshare?i…

六.总结阶段

学习完防抖,我想了一下,为什么节流要用时间戳的方式实现,而不根据定时器呢。
我的理解是这样的,防抖重在重置,定时器是个变量,而限流重在规律执行,相对而言定时器是个常量。
我们只能声明一个第三方变量进行控制。

回复

我来回复
  • 暂无回复内容