首页 > 其他分享 >详解防抖和节流函数

详解防抖和节流函数

时间:2023-02-07 14:44:25浏览次数:47  
标签:防抖 节流 debounce timer 详解 执行 函数

本文转自:https://www.jianshu.com/p/f9f6b637fd6c

闭包的典型应用就是函数防抖和节流,本文详细介绍函数防抖和节流的应用场景和实现。

函数防抖(debounce)

函数防抖,就是指触发事件后,在 n 秒后只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数的执行时间。

简单的说,当一个动作连续触发,只执行最后一次。

打个比方,坐公交,司机需要等最后一个人进入才能关门。每次进入一个人,司机就会多等待几秒再关门。

函数节流(throttle)

限制一个函数在一定时间内只能执行一次

举个例子,乘坐地铁,过闸机时,每个人进入后3秒后门关闭,等待下一个人进入。

为了方便理解,我们首先通过一个可视化的工具,感受一下三种环境(正常情况、函数防抖情况 debounce、函数节流 throttle)下,对于mousemove事件回调的执行情况。

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

常见的应用场景

函数防抖(debounce)的应用场景

连续的事件,只需触发一次的回调场景有:

  • 搜索框搜索输入。只需要用户最后一次输入完再发送请求
  • 手机号、邮箱格式的输入验证检测
  • 窗口大小的 resize 。只需窗口调整完成后,计算窗口的大小,防止重复渲染。

函数节流(throttle)的应用场景

间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚动到底部监听
  • 谷歌搜索框,搜索联想功能
  • 高频点击提交,表单重复提交
  • 省市信息对应字母快速选择

实现原理

函数防抖(debounce)

简单实现:

const debounce = (func, wait) => {
    let timer
    return () => {
		clearTimeout(timer)
        timer = setTimeout(func, wait);
    }
}

函数防抖在执行目标方法时,会等待一段时间。当又执行相同方法时,若前一个定时任务未执行完,则 清除掉定时任务,重新定时。

封装:

function debounce(fn, delay = 500) {
    // timer 是在闭包中的
    let timer = null;
    
    return function() {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}

// test debounce 返回一个函数
input1 = document.getElementById('input1')
input1.addEventListener('keyup', debounce(function () {
    console.log(input1.value)
}, 600))

绑定事件解释:addEventListener 第一个参数是监听的事件,第二个参数是对应事件的回调函数。将 debounce 函数作为回调函数,这个 debounce 回调函数返回一个防抖之后的函数,因此实现了防抖的功能。

防抖解释:当 按下某个键的时候触发 keydown 事件,并执行回调。timer 默认为 null,在 return 的函数中定时器 timer 被赋值,如果在 delay 延迟之内再次触发了 keydown 事件,那么 timer 就会被重置为null...,当用户输入完成之后(delay 时间已过),那么就会触发 debounce 中的回调函数,也就是 keydown 最终要执行的事件。

函数节流(throttle)

简单实现

const throttle = (func, wait) => {
    let timer;
    
    return () => {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            func();
            timer = null
        }, wait)
    }
}

函数节流的目的,是为了限制函数一段时间内只能执行一次。因此,通过使用定时任务,延时方法执行。在延时的时间内,方法若被触发,则直接退出方法。从而实现一段时间内只执行一次。

封装:

function throttle(fn, delay) {
    let timer = null
    
    return function() {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        })
    }
}
// test
let div1 = document.getElementById('div1')
div1.addEventListener('drag', throttle(function(e) {
    console.log(e.offsetX, e.offsetY)
}, 100))

解释:如果 timer 存在,那就直接返回,不再往下执行了。这样就实现了一段时间内执行一次的目的。

异同比较

相同点:

  • 都可以通过使用 setTimeout 实现
  • 目的都是,降低回调函数的执行频率,节省计算资源

不同点:

  • 函数防抖,是在一段连续操作结束之后,处理回调,利用 clearTimout 和 setTimeout 实现。函数节流,是在一段连续操作中,每一段时间只执行一次,在频率较高的事件中使用来提高性能。
  • 函数防抖关注一段时间内连续触发,只在最后一次执行;而函数节流侧重于在一段时间内只执行一次。

参考资料

标签:防抖,节流,debounce,timer,详解,执行,函数
From: https://www.cnblogs.com/mmzuo-798/p/17098354.html

相关文章

  • MQTT协议详解
    MQTT协议详解 MQTT是基于Publish/Subscribe(发布订阅)模式的物联网通信协议特点:简单易实现支持Qos(服务质量)报文小MQTT协议构建于TCP/IP协议之上发布订阅模式:......
  • 动态代理详解
        ......
  • ClassNames库详解
    简述ClassNames是一个用于有条件处理classname字符串连接的库,非常好用~。简单来说就是动态地去操作类名,把符合条件的类名粘在一起。安装(使用npm)npminstallcl......
  • File类详解--Java基础083
    packagecom.sqf.file;importjava.io.File;importjava.io.IOException;/*File类的构造方法:File(Stringpathname)指定文件或者文件夹的路径创建一个File文件......
  • seaborn详解
    #coding=utf-8importseabornassnsimportnumpyasnpimportmatplotlibasmplimportmatplotlib.pyplotaspltdefsinplot(flip=1):x=np.linspace(0,14,100)......
  • pannas详解
    #coding=utf-8'''pannas的函数作用;read_csv(文件的路径)读取文件<class'pandas.core.frame.DataFrame'>(read_csv返回的对象)对象的方法与属性:属......
  • 详解Spring AOP自定义可重复注解没有生效问题
    目录1.问题背景2.不啰嗦,上代码3.问题排查3.1是不是切点写得有问题,于是换成如下形式:3.2是不是使用的地方不是代理对象4.问题原因 1.问题背景工作中遇......
  • tensorflow中slim详解
    1.变量的定义 from__future__importabsolute_importfrom__future__importdivisionfrom__future__importprint_functionimporttensorflowastfslim=tf.contrib......
  • python3中zip详解
    描述zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象......
  • 一文详解TensorFlow模型迁移及模型训练实操步骤
    摘要:本文介绍将TensorFlow网络模型迁移到昇腾AI平台,并执行训练的全流程。然后以TensorFlow1.15训练脚本为例,详细介绍了自动迁移、手工迁移以及模型训练的操作步骤。本文分......