js关于防抖和节流的问题

目录

一、防抖

1、防抖代码编写

2、添加一个是否立即执行的参数flag

3、防抖应用场景

 二、节流

1、节流函数编写

时间戳

定时器

时间戳 + 定时器。

2、节流场景

scroll 滚动

input 动态搜索

三、总结

四、防抖的库


防抖和节流的话题,无论是在面试还是在实际场景的应用过程中都,是一个出现频率很高的话题。本文就这两个话题,做一个全面的梳理。 

一、防抖

  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

这句话的意思是:防抖就是要延迟执行,你一直操作触发事件一直不执行,当你停止操作等待多少秒后才执行。也就是说不管事件触发频率有多高,一定在事件触发 n 秒后执行。如果在事件触发的 n 秒又触发了这个事件,那就以新事件的事件为准,n 秒后才执行。总之,要等你触发完事件 n 秒内不再触发事件,它才执行。

1、防抖代码编写

根据定义,我们知道要在时间 n 秒后执行,那么我们就用定时器来实现:

function debounce(event, wait) {
    let timer = null;
    return function (...args) {
      clearTimeout(timer); // 清除setTimeout,使其回调函数不执行
        timer = setTimeout(() => {
            event.apply(this, args)
        }, wait)
    }
}

2、添加一个是否立即执行的参数flag

代码很简单,即当还在触发事件时,就清除 timer,使其在 n 秒后执行,但此写法首次不会立即执行,为其健壮性,需加上判断是否第一次执行的第三个参数 flag,判断其是否立即执行。

function debounce(event, wait, flag) {
    let timer = null;
    return function (...args) {
        clearTimeout(timer)
        if (!timer && flag) {
            event.apply(this, args)
        } else {
            timer = setTimeout(() => {
                event.apply(this, args)
            }, wait)
        }
    }
}

3、防抖应用场景

窗口大小变化,调整样式

window.addEventListener('resize', debounce(handleResize, 200))

搜索框,输入后1000毫秒搜索

debounce(fetchSelectData, 300)

表单验证,输入 1000 毫秒后验证

debounce(validator, 1000)

其他诸如,登录、点击按钮提交表单、点赞、收藏、标心… 等等。

 二、节流

  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

 顾名思义,一节一节的流,就好似控制水阀,在事件不断触发的过程中,固定时间内执行一次事件。

1、节流函数编写

因为是固定时间内执行一次时间,所以我们有两种实现方法,一用时间戳,二用定时器。

时间戳
function throttle(event, wait) {
    let pre = 0;
    return function (...args){
        if (new Date() - pre > wait) {
            // 当 n 秒内不重复执行
            pre = new Date();
            event.apply(this, args)
        }
    } 
}

使用时间戳虽然能实现节流,但是最后一次事件不会执行。

定时器
function throttle(event, wait) {
    let timer = null;
    return function (...args) {
        if (!timer) {
            timer = setTimeout(() => {
                timer = null;
                event.apply(this, args)
            }, wait)   
        }
    }
}

使用定时器实现节流,虽然最后一次能触发,但是第一次不会触发。

时间戳 + 定时器。

为解决第一次和最后一次都可以触发,把两者结合起来。

function throttle(event, wait) {
    let pre = 0, timer = null;
    return function (...args) {
        if (new Date() - pre > wait) {
            clearTimeout(timer);
            timer = null;
            pre = new Date();
            event.apply(this, args)
        } else {
            timer = setTimeout(() => {
                event.apply(this, args)
            }, wait)
        }
    }
}

2、节流场景

scroll 滚动
window.addEventListener('scroll', throttle(handleScroll, 200))
input 动态搜索
throttle(fetchInput, 300)

三、总结

防抖:只执行最后一次。事件持续触发,但只有等事件停止触发后 n 秒后才执行函数。

节流:控制执行频率。持续触发,每 n 秒执行一次函数。

四、防抖的库

两大工具库都有防抖源码,可供参考:

相关推荐

  1. js关于问题

    2024-03-13 02:14:02       43 阅读
  2. 2024-03-13 02:14:02       32 阅读
  3. 2024-03-13 02:14:02       32 阅读
  4. vue中

    2024-03-13 02:14:02       62 阅读
  5. 概念及区别

    2024-03-13 02:14:02       37 阅读
  6. 2024-03-13 02:14:02       48 阅读
  7. 【前端】

    2024-03-13 02:14:02       65 阅读
  8. 应用场景

    2024-03-13 02:14:02       51 阅读
  9. Js面试之

    2024-03-13 02:14:02       50 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-13 02:14:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-13 02:14:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-13 02:14:02       82 阅读
  4. Python语言-面向对象

    2024-03-13 02:14:02       91 阅读

热门阅读

  1. 关 于 早 起

    2024-03-13 02:14:02       47 阅读
  2. 【二分算法】分巧克力

    2024-03-13 02:14:02       43 阅读
  3. 深入浅出队列:Python中的数据驱动力

    2024-03-13 02:14:02       46 阅读
  4. KSR-imp通过vcpkg安装CGAL

    2024-03-13 02:14:02       44 阅读
  5. 字符串|344.反转字符串

    2024-03-13 02:14:02       39 阅读
  6. CatBoost模型部署与在线预测教程

    2024-03-13 02:14:02       44 阅读
  7. 第十节 JDBC事务

    2024-03-13 02:14:02       46 阅读
  8. Spring Boot 实现文件本地以及OSS上传

    2024-03-13 02:14:02       43 阅读