ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

网站开发进阶(六十八)防抖节流

2021-07-18 18:01:35  阅读:204  来源: 互联网

标签:function 防抖 func 进阶 timeout 六十八 节流 wait


文章目录


一、前言 - 为什么要防抖或节流

实现防抖或节流,主要基于以下目的:

  • 及时查询时,减少服务器压力。
  • 频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。
  • 需求是以一定的频率执行后续的处理。

二、防抖 (debounce)

所谓防抖,就是把触发非常频繁的事件合并成一次去执行,以免把一次事件误认为多次。即在指定时间内只执行一次回调函数,如果在指定的时间内又触发了该事件,则回调函数的执行时间会基于此刻重新开始计算,敲键盘就是一个每天都会接触到的防抖操作。

想要了解一个概念,必先了解概念所应用的场景。在 JS 这个世界中,有哪些防抖的场景呢?

  • 登录、发短信等按钮避免用户点击太快,以致于发送多次请求,需要防抖;
  • 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;
  • 提交表单;
  • 文本编辑器实时保存,当无任何更改操作一秒后进行保存;
  • input 事件(当然也可以用节流,实现实时关键字查找);

实现原理

  • 只要触发,就会清除上一个计时器,又注册新的一个计时器。直到停止触发wait时间后,才会执行回调函数。

  • 不断触发事件,就会不断重复这个过程,达到防止目标函数过于频繁调用的目的。

逻辑代码如下,可以看出来「防抖重在清零 clearTimeout(timer)

function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }

三、节流 (throttle)

节流,顾名思义,控制水的流量。控制事件发生的频率,如控制为1s发生一次,甚至1分钟发生一次。与服务端(server)及网关(gateway)控制的限流 (Rate Limit) 类似。

  • scroll 事件,每隔一秒计算一次位置信息等;
  • 浏览器播放事件,每隔一秒计算一次进度信息等;
  • input 框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可防抖实现);

实现原理

  • 只要触发,只会在当前计时器为空时,注册计时器。

  • 不断触发事件,只会在固定的事件间隔触发。

有2种方式实现节流:setTimeout时间戳

setTimeout

function throttle(func, wait) {
  let timeout;
  return function () {
    if (!timeout) {
      timeout = window.setTimeout(function () {
        func.apply(this, arguments);
        timeout = null;
      }, wait);
    }
  };
}

时间戳

function throttleTime(func, wait) {
  let prev = 0;
  return function () {
    let now = Date.now();
    if (now - prev > wait) {
      func.apply(this);
      prev = now;
    }
  };
}

从以上逻辑代码可以看出来「节流重在开关锁 timer=null

四、总结

  • 防抖:防止抖动,单位时间内事件触发会被重置,避免事件误触发多次。

  • 节流:控制流量,单位时间内事件只能触发一次,如果服务器端的限流即 Rate Limit
    在这里插入图片描述

五、示例代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="bt1">防抖</button>
    <button id="bt2">节流</button>
  </body>
  <script>
    // 防抖
    function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }
    // 节流
    function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
    function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }
    let bt1 = document.getElementById("bt1");
    let bt2 = document.getElementById("bt2");
    bt1.onclick = debounce(function () {
      console.log(1);
    }, 1000);
    bt2.onclick = throttleTime(function () {
      console.log(2);
    }, 1000);
  </script>
</html>

标签:function,防抖,func,进阶,timeout,六十八,节流,wait
来源: https://blog.csdn.net/sunhuaqiang1/article/details/118763871

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有