vue 节流函数防抖函数封装

5,392 阅读3分钟

概念

  • 节流 节流的意思是,规定时间内,只触发一次。比如我们设定500ms,在这个时间内,无论点击按钮多少次,它都只会触发一次。具体场景可以是抢购时候,由于有无数人快速点击按钮,如果每次点击都发送请求,就会给服务器造成巨大的压力,但是我们进行节流后,就会大大减少请求的次数。
  • 防抖 防抖的意思是,在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效。具体场景可以搜索框输入关键字过程中实时 请求服务器匹配搜索结果,如果不进行处理,那么就是输入框内容一直变化,导致一直发送请求。如果进行防抖处理,结果就是当我们输入内容完成后,一定时间(比如500ms)没有再 输入内容,这时再触发请求。

下面简单画下流程图

xxx.png

节流 throttle

在高频触发回调函数时,节流操作使回调函数在每隔一段时间定期执行一次,时间间隔内再触发,不会重新执行。

核心在于让一个函数不要执行的太频繁,减少一些过快的操作。

类似于王者中技能冷却时间。

// 方式一:使用时间戳 (时间戳版本会优先执行,点击立马执行一次)
export const throttle1 = (fn, delay = 1000) => {
  //距离上一次的执行时间
  let lastTime = 0;
  return function () {
    let _this = this;
    let _arguments = arguments;
    let now = new Date().getTime();
    //如果距离上一次执行超过了delay才能再次执行
    if (now - lastTime > delay) {
      fn.apply(_this, _arguments);
      lastTime = now;
    }
  };
};

// 方式二: 使用定时器 (定时器版本会后置执行,点击需等待delay时间之后执行)
export const thorttle2 = (fn, delay = 1000) => {
  // 接收定时器的地址
  let timer = null;
  return function () {
    let _this = this;
    let args = arguments;
    // 如果等到了delay才能执行并清空定时器
    if (!timer) {
      timer = setTimeout(function () {
        timer = null;
        fn.apply(_this, args);
      }, delay);
    }
  };
};

防抖 debounce

在高频触发回调函数时,防抖操作使回调函数在一定时间间隔内,再次触发会清空定时器,并重新计时;计时结束后输出一次结果。

核心在于,在短时间内大量触发同一事件时,只会执行一次回调函数。避免把一次事件误认为多次。

/**
 *
 * @param {*} fn  是我们需要包装的事件回调
 * @param {*} delay 是每次推迟执行的等待时间
 */
const debounce = (fn, delay = 1000) => {
  // 定时器
  let timer = null;
  // 将debounce处理结果当作函数返回
  return function() {
    // 保留调用时的this上下文
    let context = this;
    // 保留调用时传入的参数
    let args = arguments;
    // 每次事件被触发时,都去清除之前的旧定时器
    if (timer) {
      clearTimeout(timer);
    }
    // 设立新定时器
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
};
export default debounce;

常见使用场景

  • 监听 scroll、mousemove 等事件 - 节流(每隔一秒计算一次位置)
  • 监听浏览器窗口 resize 操作 - 防抖(只需计算一次)
  • 键盘文本输入的验证 - 防抖(连续输入文字后发送请求进行验证,验证一次就好)
  • 提交表单 - 防抖(多次点击变为一次)
  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
  • 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖

节流、防抖有时用哪个都可以,比如监听页面滚动,可以节流(每个一段时间出发一次回调),也可以防抖(用户当前这次滚动结束出发,继续滚动等待下一次触发)

vue中使用

index.vue

<script>
	import debounce from "../utils/debounce";
        import throttle from "../utils/throttle";
	
	methods:{
		// 防抖方法
		change: debounce (function () {
			// 逻辑
		},1000)

		// 节流方法
		change: throttle(function () {
			// 逻辑
        },1000)
	}
</script>

总结

  • 函数防抖和函数节流都是防止某一时间频繁触发,但是这两兄弟之间的原理却不一样。
  • 函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

代码示例