debounce防抖函数,throttle节流函数

所需知识点

  • 闭包
  1. 闭包的特点:
    (1) 函数内部可以引用外部的参数和变量
    (2) 参数和变量保存在内存中,不会被垃圾回收机制回收(全局变量也会长期保存在内存中)
  2. 缺点:使用不当,容易造成内存泄漏
  3. 全局变量和局部变量是否可以累加?
    (一般情况,全局变量可以累加,而局部变量不能累加,闭包除外)
  4. 很详细 https://segmentfault.com/a/1190000000652891
全局变量的累加:  (全局变量可以累加)



-----------------------------------------------------------------


局部变量的累加: (局部变量不能累加)



-----------------------------------------------------------------


闭包中变量的累加: (闭包可以累加变量)
注意: 因为闭包常驻内存中,所以在执行完后,手动清掉
如下面: y = null; 即时清掉
   
  • 闭包在react中的使用(事件和闭包)
  1. 点击事件普通函数
  2. 点击事件闭包

点击事件:普通函数,传参
this.common(e, 'anthorParams') }>点击普通函数
common = (e: React.MouseEvent, anthor: string ): void => { console.log(e.target); console.log(anthor); } 点击事件:闭包,传参
点击闭包函数
----!!注意这里相当于closure('name')() closure = (name: string) => { console.log(name, '1'); -------------------------- 注意:‘1’只会执行一次 // 比如 let a = 1; // 重点:闭包外层变量a能保存在内存中,是因为let a = 1执行一次就没有再从新赋为 1 // 这也就解释了上面console 1 的时候,为什么只执行了一次 return (e: React.MouseEvent) => { -------- e 在这里获取 console.log(e.target); console.log(name, '2'); ------------------------- 注意:‘2’会多次执行 }; }

防抖函数 debounce

特点:延时执行,如果在延时的时间内多次触发,则从新计时

延迟执行,设置一个延迟时间a,在事件A发生时,延迟a秒执行事件A,
如果A发生后,a秒内有新的同一事件再次发生,则a从新计时(即又要再延时a秒才会触发事件A)

节流函数 throttle

特点:每隔一段时间,只执行一次

在时间a内,只执行一次函数,多次触发,也只执行一次

debounce防抖函数,throttle节流函数_第1张图片
来源于网络

竖线的疏密代表事件执行的频繁程度。可以看到,正常情况下,竖线非常密集,函数执行的很频繁。而debounce(函数防抖)则很稀疏,只有当鼠标停止移动时才会执行一次。throttle(函数节流)分布的较为均已,每过一段时间就会执行一次。





debounce函数

原理:
在闭包中设置一个变量来保存setTimeout上一次的状态,有新的输入的时候,清除定时器,再开启一个新的定时器,即重新延迟执行事件

点击debounce函数
debounce = (delay: number) => { let timer: any = null; ---- 闭包中的状态保存在内存中,不会被垃圾回收机制清除,所以能保存上一次的状态 return () => { if (timer) { window.clearTimeout(timer); ----- 只要有新的输入,就清掉上一次的定义器,从新执行新的定时器 } timer = window.setTimeout(() => { console.log('11111111111'); }, delay); }; }

throttle函数

原理
用闭包设置一个变量开关a,a默认为true,点击后,执行闭包
先判断a的值( 决定是否执行定时器 ),
再把a变为false(目的是为了在规定的延时时间内,再次点击,不再执行定时器 ),
delay秒后,再执行定时器,a变为true,就又会执行定时器了。

点击throttle函数
throttle = (delay: number) => { let isRun: boolean = true; return () => { if (!isRun) { return; } isRun = false; window.setTimeout(() => { console.log('111111'); isRun = true; }, delay); }; }

利用时间戳,实现throttle函数

export const throttle = (fn,wait) => {
    var previous = null; //记录上一次运行的时间
    var timer = null;

    return function(){
        var now = +new Date();
        if ( !previous ) {
            previous = now;
        }
        if(now - previous > wait){
            clearTimeout(timer); -----  这里在时间到后默认会执行一次,如果不想执行,直接return即可
            fn();
            previous = now;   
        }else{
            clearTimeout(timer);
            timer = setTimeout(function(){
                fn();
            },wait);
        }
    }
}


let a = +new Date()
等于
let a = new Date().valueOf()   ----- 返回实例对象距离时间零点对应的毫秒数
也等于
let a = new Date().getTime() 

详细:https://juejin.im/entry/58c0379e44d9040068dc952f
精简:https://segmentfault.com/a/1190000008768202
完美:https://www.jianshu.com/p/f9f6b637fd6c

2019/3/26复习
throttle-Date版本:now-last>delay时,执行函数,小于时不执行,要保证第一次要执行,所以把last初始值设置为0




  
  
  
  Document


  
debounce防抖函数-点击
throttle节流函数-点击 setTime版
throttle节流函数-点击 Date版本

你可能感兴趣的:(debounce防抖函数,throttle节流函数)