JS的防抖(debounce)如何更合理?

debounce(防抖)

做项目时第一次听到这个名词,一脸蒙B。今天有时间就了解了一下这是什么概念?目的就是防止用户点击过快导致数据提交多次。

我们把时间拉长就能更好的理解,例如规定10秒内只有一次点击生效,时间从0开始点击一次,如果在1,2,3...9秒时间点上再点击是无效的,当时间大于10秒的时候,再点击就可以生效了。

网上能查到的实现原理都是使用setTimeout延时执行代码,还是上面的例子,0秒点击时启动一个定时器,10秒后生效,这不大友好,因为这是第一次点击应该马上执行。

如果第3秒又点击了一下,那么清除上面的定时器,第3+10=13秒后生效,如果一直点一直延时10秒,不大友好。

所以我改进了一下,让它真正做到规定时间间隔内执行一次代码,如果是新点击则马上执行代码,在时间间隔内连续点击则清除上一次定时器,并计算与终点时间之差启动新定时器。例如(第一次)0秒点击了一次马上执行,第5秒(第二次)点击了一次,时间差=10-5=5秒,5秒后执行代码则是第10秒。如果第25秒(第三次)点击一次也马上执行,因为上一次的时间间隔期是第20秒已经过了则为新点击。

事例代码如下

/**

 * 防抖,时间间隔内只执行一次代码

 * @param {Function} fn 需要防抖处理的函数

 * @param {number} wait 时间间隔

 * @returns

 */

function debounce(fn, wait) {

  /** 上一次执行 fn 的时间 */

  let previous = 0;

  /** 定时器 */

  let timer = null;

  /** 定时器时间 */

  let wait_remain = 0;

  // 将 debounce 处理结果当作函数返回

  return function (...args) {

    // 获取当前时间,转换成时间戳,单位毫秒

    let now = +new Date();

    if (timer) {

      clearTimeout(timer);

    }

    //定时器时间 = 总间隔-上次运行到现在用时

    wait_remain = wait - (now - previous);

    // 如果定时器时间>0则继续运行定时器

    if (wait_remain > 0) {

      // 定时器时间结束后执行函数 fn

      timer = setTimeout(() => {

        previous = +new Date();

        fn.apply(this, args);

      }, wait_remain);

      return;

    }

    // 第一次执行

    // 或者时间间隔超出了设定的时间间隔,执行函数 fn

    previous = now

    fn.apply(this, args)

  }

}

//使用防抖10秒时间间隔
test = debounce(() => {
console.log(new Date());
}, 1000*10);

//每5秒运行一次
test();
setInterval(() => {
  test();
}, 1000*5);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值