防抖节流函数是什么

防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。通俗来说就是n个事件发生了,我只认最后一次。比如一个需求,一个输入框,当我输入内容之后会请求接口搜索出与输入框内容相关的数据,这个输入框的change事件在输入的时候高频触发,如果每次改变都去请求接口会造成很大的性能问题,这个时候的做法可能是当我停止输入一秒之后再去请求接口,就只会发起一次请求

节流:高频事件触发的时候,每隔n秒执行一次。防抖函数的弊端–当我一直输入一直不停那么函数就一直不会被执行,这很容易被用户以为该程序是不是卡了,造成不好的用户体验,此时每隔n秒执行一次函数,给用户反馈就很重要了,这就是节流的用法


1.防抖函数封装

在项目中新建一个js文件utils.js

const utils = {}
/**
 * 防抖
 * @param {*} fn 需要防抖的方法
 * @param {*} delay 防抖时间
 * @returns
 */
utils.debounce = function(fn, time) {
  // 等待的时间默认200ms 
  let delay = time || 200;
  let timer = null;
  return function () {
    const _this = this;
    // 保存调用时传来的参数
    const args = arguments;
    // 每次事件被触发时,都清除之前的旧定时器
    if (timer) {
      clearTimeout(timer);
    }
    // 函数延迟执行
    timer = setTimeout(function () {
      fn.apply(_this, args);
    }, delay);
  };
}
export default utils;

调用封装的防抖函数

// 先引入函数
import utils from '@/assets/js/utils.js'
// 方法,注意此处不能使用箭头函数,否则this指向会有问题
handleScroll:utils.debounce(function(e) {
	// 此处写自己的逻辑
}, 500)

2.防抖函数先执行再等待

此时的问题是我一直在操作怎么没有反应呢,防抖函数上面说了是只认最后一次,可不可以让我先执行一次你再去等待啊,那么我们上面的函数升级一下,增加一层anOnce立即执行的判断,当我传入atOnce时就先执行一次,否则还是按正常的防抖函数走,满足不同的使用场景

/**
 * 防抖
 * @param {*} fn 需要防抖的方法
 * @param {*} delay 防抖时间
 * @param {*} atOnce 是否需要立即执行
 * @returns
 */
utils.debounce = function(fn, time, atOnce) {
  let delay = time || 200;
  let timer = null;
  let count = 0;
  return function () {
    const _this = this;
    const args = arguments;
    // 如果是立即执行
    if (atOnce) {
      // 第一次直接执行不用等 
      if (count == 0) {
        fn.apply(_this, args);
        count ++;
      } else {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(function () {
          fn.apply(_this, args);
        }, delay);
      }
    //   
    } else {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(function () {
        fn.apply(_this, args);
      }, delay);
    }
  };
}

调用

handleScroll:utils.debounce(function(e) {
	// 此处写自己的逻辑
}, 500, true)

3.节流函数的封装

/**
 * 节流
 * @param {*} fn 需要节流的方法
 * @param {*} interval 多久执行一次节流
 * @returns
 */
utils.throttle = function(fn, time) {
  let last;
  let timer;
  let interval = time || 200;
  return function () {
      const _this = this;
      const args = arguments;
      let now = +new Date();
      if (last && now - last < interval) {
          clearTimeout(timer);
          timer = setTimeout(function () {
              last = now;
              fn.apply(_this, args);
          }, interval);
      } else {
          last = now;
          fn.apply(_this, args);
      }
  }
}

调用

handleScroll:utils.throttle(function(e) {
	// 此处写自己的逻辑
},  500)

4.lodash库防抖节流函数的使用

文档
文档里面很详细,也同样封装了是否防抖前执行,节流前执行


// 安装
npm i --save lodash
// 引入
import _ from 'lodash'
// 防抖
handleScroll:_.debounce(function(e) {
	// 此处写自己的逻辑
},  500)
// 节流
handleScroll:_.throttle(function(e) {
	// 此处写自己的逻辑
},  500)

如有错误的地方请指正

Logo

前往低代码交流专区

更多推荐