【防抖和节流】Vue和React当中的防抖和节流处理

6 篇文章 0 订阅
4 篇文章 0 订阅

1 防抖和节流函数

/**
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 * 防抖又分为立即执行和延迟执行
 * - 立即执行:点击第一次就会执行,后续指定时间内的点击不会生效
 * - 延迟执行:指定时间内不再进行点击,也就是过了这个指定时间,才会执行一次函数,前面的n次点击不会生效
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function debounce(func, wait = 500, immediate = true) {
  let timer = null;
  return function (...args) {
    // 如果存在定时器,则还处在等待期间,则清除定时器,重新开始计算时间
    if (timer) {
      clearTimeout(timer);
    }

    if (immediate) {
      // 如果是立即执行,则第一次进入的时候,定时器为空,会立即执行一次,然后立即开启一个定时器
      // 短时间内触发第二次时,定时器是不为空的,那么就不会执行,只有等定时器走完,清除了timer,才会再次执行
      // 这样也就实现了第一次点击立即执行,后面过了指定时间,定时器为空,才会再次执行
      // 注意:需要注意参数和this绑定的处理
      if (!timer) {
        typeof func === "function" && func.apply(this, args);
      }
      timer = setTimeout(() => {
        timer = null;
      }, wait);
    } else {
      // 设置定时器,定时器正常走完才会执行方法,也就是指定时间内没有再次触发,才会执行
      timer = setTimeout(() => {
        typeof func === "function" && func.apply(this, args);
      }, wait);
    }
  };
}

/**
 * 节流原理:当持续触发事件时,有规律地每隔一个时间间隔执行一次事件处理函数
 * 适用于大量触发事件的场景,譬如监听滚动事件、鼠标滑动事件等
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
function throttle(func, wait = 500, immediate = true) {
  let isCanExecute = true; // 是否可以执行函数
  return function (...args) {
    if (immediate) {
      // 立即执行
      if (isCanExecute) {
        isCanExecute = false;
        typeof func === "function" && func.apply(this, args);
        setTimeout(() => {
          isCanExecute = true;
        }, wait);
      }
    } else {
      // 延迟执行
      // 第一次触发,处于可以执行的状态,会进入判断,状态设置为不可以执行,同时开启定时器,定时器当中会执行函数,执行完函数,会重置状态为可以执行
      // 第二次触发时,处于不可执行状态,不会进入判断,只有当内部的定时器走完后,状态设置为了true,才会进入判断,才会开启定时器
      if (isCanExecute) {
        isCanExecute = false;
        setTimeout(() => {
          typeof func === "function" && func.apply(this, args);
          isCanExecute = true;
        }, wait);
      }
    }
  };
}

2 Vue当中的写法

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Vue</title>
  </head>
  <body>
    <div id="app">
      <button @click="handleDebounceClick(1, 2)">按钮-防抖</button>
      <button @click="handleThrottleClick(1, 2)">按钮-节流</button>
    </div>
  </body>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
  <!-- utils.js文件的内容就是上述的两个函数 -->
  <script src="../utils.js"></script>
  <script>
    new Vue({
      el: "#app",
      data: {
        num: 123,
      },
      methods: {
        // 防抖
        handleDebounceClick: debounce(function (data1, data2) {
          console.log(this.num); // 读取data当中的数据
          console.log(data1); // 读取参数1
          console.log(data2); // 读取参数2
        }),
        // 节流
        handleThrottleClick: throttle(function (data1, data2) {
          console.log(this.num); // 读取data当中的数据
          console.log(data1); // 读取参数1
          console.log(data2); // 读取参数2
        }),
      },
    });
  </script>
</html>

3 React当中的写法

// utils.js文件的内容就是上述的两个函数
import { debounce, throttle } from "../utils.js";
function Demo(props) {
  // 防抖
  const handleDebounceClick = debounce((data1, data2) => {
    console.log(data1); // 读取参数1
    console.log(data2); // 读取参数2
  });
  // 节流
  const handleThrottleClick = throttle((data1, data2) => {
    console.log(data1); // 读取参数1
    console.log(data2); // 读取参数2
  });

  return (
    <React.Fragment>
      <button onClick={() => handleDebounceClick(1, 2)}>按钮-防抖</button>
      <button onClick={() => handleThrottleClick(1, 2)}>按钮-节流</button>
    </React.Fragment>
  );
}
v3的输入框(通常是指VueReact前端框架中的Input组件)实现防抖(debounce)和节流(throttle)是为了优化用户体验,减少频繁操作导致的无意义请求。以下是这两种策略的简要说明: 1. 防抖(Debounce):当用户停止连续输入一段时间后才触发事件处理函数。这样可以防止短时间内连续输入触发多次请求,比如搜索建议或实时更新。常见的做法是在输入事件结束后设置一个定时器,在这个时间段内如果再次输入,则清除旧定时器并重新设置一个新的。 ```javascript function debounce(fn, delay) { let timeout; return function() { const context = this; clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(context, arguments); }, delay); }; } ``` 在Vue的自定义事件里,你可以这样应用防抖: ```javascript methods: { handleInputChange(event) { this.searchTerm = event.target.value; // 使用防抖函数,延迟1秒触发搜索 this.search(debounce(this.performSearch, 1000)); }, performSearch() { // 实际的搜索逻辑 } } ``` 2. 节流(Throttle):则是限制在一定时间内只执行一次事件处理函数,即使用户持续快速输入也是如此。它会在用户停止输入后再执行函数,但是如果有新的输入发生,会取消之前计划的函数执行,并立即执行新的。 ```javascript function throttle(fn, delay) { let timeout; return function() { const context = this; clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(context, arguments); }, delay); }; } ``` 同样地,用于输入框的事件处理可能会像这样: ```javascript handleInputChange throttledInputChange = throttle(this.handleInputChange, 300); ``` 这会让搜索事件每300毫秒只执行一次。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值