美文网首页
js - 防抖和节流

js - 防抖和节流

作者: 梁庄十年 | 来源:发表于2021-11-28 18:09 被阅读0次

    1 防抖 (debounce)

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

    • case1 : 直接在单个vue组件中定义的防抖函数
    <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>
    
    • case2 定义成公共方法, 供全局使用

    在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();
            }
          })();
        },
    }
    

    相关文章

      网友评论

          本文标题:js - 防抖和节流

          本文链接:https://www.haomeiwen.com/subject/wddxtrtx.html