写一个防抖和节流

142 阅读2分钟

序言:防抖和节流是前端常用避免无效的重复操作的方法。

防抖

防抖是指触发事件后在规定时间内回调函数只能执行一次,如果在规定时间内触发了该事件,则会重新开始算规定时间。关注两点,由于触发要重新计算时间,所以重点是防止操作在短时间反复执行。

防抖的两种实现和常用场景:

  • 触发事件之后非立即执行版本,常用场景比如输入联想,在一定时间内输入不更新再去请求联想结果,减少中间不必要的查询,防止反复的刷新页面。
  • 触发事件之后立即执行版本,比如点赞,收藏等操作,点击之后立即执行,在一定时间内点击就会刷新计时,不会再执行操作。

延迟执行实现代码和思路:

var debounce(callback, delay = 500) =>{
    let timer = null;
    return function(args){
        if(timer){
           clearTimeout(timer);
           timer = null;
        }
        timer = setTimeOut(()=>{
            callback.call(args);
        },delay);
    }
}

使用和结果:

截屏2022-02-20 下午10.37.20.png

可以看到虽然调用了两次dF方法,但是实际回调只调用了一次,并且延迟时间是刷新过,用了大概 1100ms 左右。

立即执行实现思路和代码:

基于上面的版本修改一下,函数创建时如果定时器为空就执行任务,否则刷新定时器,定时器结束的时候要记得把存储定时器的缓存清理掉
var debounce = (callback, delay = 500) => {
    let timer = null;
    return function (args) {
        if (timer === null) {
            callback.call(args);
        }
        timer = setTimeout(() => {
            timer = null;
        }, delay);
    }
}

使用和结果:

截屏2022-02-20 下午10.48.12.png

可以看到任务在方法调用后几ms就执行了,第二次调用因为还没有到规定的时间1000ms,所以没执行,第三次调用再次执行了。

节流

节流是指在规定的时间内只执行一次回调,重点是只执行一次,但是不刷新定时器,重点是在时间范围内操作只能执行一次,从名称上也能看出来。

节流的实现和场景

  • 触发之后实现,但是不刷新定时器,比如表单提交的时候点击确定之后在规定时间内不再允许再次点击提交按钮

节流的实现代码和思路:

var throttle = (callback, delay) => {
    let timer = null;
    return (args) => {
        if (timer) {
            return;
        }
        timer = setTimeout(() => {
            clearTimeout(timer);
            timer = null;
        }, delay);
        callback(args);
    }
}

使用和结果:

截屏2022-02-20 下午11.07.02.png