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)要求最后一个事件触发完毕后再执行。

  • 相关阅读:
    [python]OS文件系统
    [phyton]文件的简单读写练习
    [Python]字典的简单用法
    Cocos2d-x学习笔记(十五)之 绘制图形
    Cocos2d-x学习笔记(十四)之 拖动渐隐效果类CCMotionStreak
    Cocos2d-x学习笔记(十三)之 容器类
    Cocos2d-x学习笔记(十二)之 文本渲染类
    Cocos2d-x学习笔记(十一)之 菜单类CCMenu
    Cocos2d-x学习笔记(十)之 控件类CCControl
    Cocos2d-x学习笔记(九)之 摄像机类CCCamera
  • 原文地址:https://www.cnblogs.com/Peter2014/p/13254268.html
Copyright © 2011-2022 走看看