掌握js防抖和节流

264 阅读3分钟

浅谈js防抖和节流

防抖和节流的重要性

防抖和节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。所以还是很有必要早点掌握的。同时,防抖和节流也是我们闭包当中的一部分,闭包包含了防抖和节流。

防抖(debounce)

场景:我们在写项目当中的搜索功能时,如果我们每输入一个字符就调用一次接口,会导致请求过于频繁,而且请求并没有意义,只有最后一次的调用接口才是有意义的
思路:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后:

  • 如果在200ms内没有再次触发滚动事件,那么就执行函数
  • 如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时

效果:如果短时间内大量触发同一事件,只会执行一次函数。
实现: 使用一个setTimeOut计时器,用一个变量来保存时间,考虑维护全局纯净,用一个闭包函数时间:

function debounce(fn,delay){
    let timer; //定时器
    return function(...args){ //形成闭包
    //args 为函数调用时传的参数
    let context = this
    timer&&clearTimeout(timer) //函数再次执行时,清除定时器,重新开始计算
    //利用定时器,让指定函数延迟执行
    timer = setTimeout(function(){//执行传入的指定函数,利用apply更改this的绑定和传参
    fn.apply(context,args)
	},delay)
    }
}

以上就是防抖实现了,那么我们可以给出一个定义:

  • 对于短时间内连续触发的事件,防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次。

节流(throttle)

看完防抖之后,我们继续思考,
但是如果产品同学的期望处理方案是:即使用户不断拖动滚动条,也能在某个时间间隔之后给出反馈呢?,这个问题我们还能用防抖来实现吗?当然是不行的,这里我们就需要用到这篇文章的第二个重点:节流
场景:当你需要监听滚动条变化,从而去计算页面中某个元素到窗口顶部距离的时候.
思路:我们可以设计一种类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活(有点类似于技能冷却时间)
效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。

function throttle(fn,delay){
    let timer;    // 定时器
    return function(...args){
        let context = this;
        // 如果timer存在,说明函数还未该执行
        if(timer) return;
        timer = setTimeout(function(...args){
            // 当函数执行时,让timer为null。
            timer = null;
            fn.apply(context,args);
        },delay);
    }
}

以上就是节流的实现了,可以我们可以给出一个定义:

  • 节流允许我们的一个函数在xxx毫秒之内只执行一次

总结:

以上是我们可以自己使用原生js来封装的防抖和节流代码,我们也可以使用lodash来实现防抖和节流操作,具体网址如下:Lodash 简介 | Lodash 中文文档 | Lodash 中文网 (lodashjs.com)

以上就是我们这篇文章所讲的防抖节流的代码以及我自己的一点点理解,如有不足,请各位大佬多多提一下自己的见解。