js - 防抖和节流

2021-11-28  本文已影响0人  梁庄十年

1 防抖 (debounce)

定义: 一段时间之后才执行某个函数; 实现方式主要是通过定时器; 防抖一般可以分为立即执行和后执行.
立即执行: 频繁触发事件, 第一次触发事件时会执行函数,后面触发如果在指定间隔时间内不会执行,过了间隔时间才会继续执行;
后执行: 频繁触发事件,事件只会在触发事件之后间隔定义的时间, 函数才会被执行, 而且只会执行最后一次触发的事件;
个人比较偏向立即执行, 下面的示例也是立即执行, 展示了局部使用和全局使用的方式;

<template>
  <div class="go-con">
    <h1>debounce</h1>
    <div class="chart-wrap">
      <button @click="privateDebounce(testFunc, 1000, ['a', 'b'])">防抖</button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'debounce',
  data () {
    return {
      timer : null,
    }
  },
  methods: {
    testFunc(params) {
      console.log('debounce');
      console.log(params);
    },
    handleResize() {
      console.log('防抖');
    },
    // 自定义防抖函数
    privateDebounce(func,wait = 500, ...args){
      let nowTimer = !this.timer; // 是否立即执行
      if(this.timer) clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        this.timer = null;
      }, wait)
      if(nowTimer) {
        func.apply(this,args)
      }
    }
  }
}
</script>

在main.js中, 将定义好的防抖函数, 挂载到 vue实例的原型上即可

function debounceFunc(func,wait = 500, ...args){
  let nowTimer = !this.timer; // 是否立即执行
  if(this.timer) clearTimeout(this.timer);
  this.timer = setTimeout(() => {
    this.timer = null;
  }, wait)
  if(nowTimer) {
    func.apply(this,args)
  }
}

Vue.prototype.$debounceFunc = debounceFunc;

在组件中使用

<template>
  <div class="go-con">
      <button @click="test">防抖 - 全局</button>
  </div>
</template>
<script>
export default {
  methods: {
    test() {
      this.$debounceFunc(this.testFunc, 1000, ['a', 'b', 'c'])
    },
  }
}
</script>

2 节流(throttle)

定义: 一段时间之内执行某个函数; 即在事件触发后,会先执行一次函数, 执行之后如果在指定的时间间隔内,用户再次触发该事件, 函数不会被执行,只有在超过了指定的时间间隔后才会再次被触发一次

<template>
  <div class="go-con">
      <button @click="throttle(getRandom, 1000)">节流</button>
  </div>
</template>
<script>
export default {
  name: 'throttle',
  data () {
    return {
      timer : null,
    }
  },
  methods: {
    throttle(func, delay, ...args) {
      if(this.timer)  return; // 如果当前有计时, 直接return;
      this.timer = setTimeout(() => {
        func.apply(this, args);
        this.timer = null; // 函数执行完, 要清除定时器, 否则无法进行下一次执行;
      }, delay)
    },
    getRandom() {
      console.log('throttle: ',Math.random());
    },
  },
}
</script>
 data () {
    return {
      prev: Date.now(),
    }
  },
 methods: {
   throttle(func, delay = 500, ...args) {
      return  (() => {
        var now = Date.now();
        if (now - this.prev >= delay) {
          func.apply(this, args);
          this.prev = Date.now();
        }
      })();
    },
}
上一篇下一篇

猜你喜欢

热点阅读