zoukankan      html  css  js  c++  java
  • JS限流与防抖

    限流

    在JS中,如果一个事件频繁触发(比如用户疯狂点击按钮)并且处理函数处理耗时还比较长,那么就容易造成性能问题。

    限流函数是针对这类问题的优化方式之一,它要求两次事件处理必须大于某个间隔时间,简而言之就是加了一层判断。

    限流函数(throttle:节流阀)的核心在于内部维护了一个“上次执行时间点”,通过比较当前执行时间与上次执行时间的差值判断是否“频繁”,是否执行。限流函数本身是一个装饰函数,修饰了事件处理器之后返回一个新的闭包函数。经过限流函数处理之后,事件触发的频率就被限制为预先传入的interval之上了。

    下面用代码实现一个限流函数:

    function throttle(fn, interval) {
      // 维护上次执行的时间
      let last = 0;
    
      return function () {
        const context = this;
        const args = arguments;
        const now = Date.now();
        // 根据当前时间和上次执行时间的差值判断是否频繁
        if (now - last >= interval) {
          last = now;
          fn.apply(context, args);
        }
      };
    }
    

    使用限流函数:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
        />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <button>click me</button>
        <script src="./throttle.js"></script>
        <script>
          const button = document.querySelector("button");
          button.addEventListener(
            "click",
            // 使用限流函数修饰事件处理器
            throttle((event) => {
              console.log("button click");
            }, 2000)
          );
        </script>
      </body>
    </html>
    

    防抖

    防抖函数也是一种限流函数,但要特殊一些。最典型的场景是表单输入,如果我们要在表单中监听input事件(比如远程搜索),那用户在输入的时候也会频繁触发,但这里使用throttle函数不行,因为我们需要等待用户停止输入一段时间后才能确认用户输入的值,所以要定义一个新的限流函数,叫做防抖函数。

    防抖(防反跳)函数的核心是内部使用定时器并维护定时器返回的ID值,如果持续触发则不断clearTimeout()并重新发起setTimeout(),通过这种方式等待事件触发完毕,然后进行延时处理。

    下面用代码实现一个防抖函数:

    function debounce(fn, delay) {
      // 记录定时器返回的ID
      let timer = null;
    
      return function () {
        const context = this;
        const args = arguments;
        // 当有事件触发时清除上一个定时任务
        if (timer) {
          clearTimeout(timer);
        }
        // 重新发起一个定时任务
        timer = setTimeout(() => {
          fn.apply(context, args);
        }, delay);
      };
    }
    

    使用防抖函数:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
        />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <input type="text" />
        <script src="debounce.js"></script>
        <script>
          const input = document.querySelector("input");
          input.addEventListener(
            "input",
            debounce((event) => {
              console.log("input finish");
            }, 2000)
          );
        </script>
      </body>
    </html>
    

    这些常用的函数可以参考lodash库

    总结

    限流函数和防抖函数都是为了应对“事件处理的速度跟不上事件触发的速度”这样的场景而产生的优化函数。

    限流(throttle)要求两次事件处理之间必须有一个间隔时间,防抖(debounce)要求最后一个事件触发完毕后再执行。

  • 相关阅读:
    openCV中cvSnakeImage()函数代码分析
    程序所有重构,升级的目标(备注,更新)
    基础总结篇之中的一个:Activity生命周期
    Tomcat全攻略
    VRRP协议具体解释
    二叉树三种遍历(递归以及非递归实现)
    AssertValid函数学习
    java定时器的使用(Timer)
    循环队列
    使用Heartbeat实现双机热备
  • 原文地址:https://www.cnblogs.com/Peter2014/p/13254268.html
Copyright © 2011-2022 走看看