防抖和节流

283 阅读2分钟

防抖就是你使劲输入,直到几秒内不操作了,才执行,如果你一直点击他就不执行, 节流就是你使劲点击,它固定几秒执行一次

防抖

防抖: 即短时间内大量触发同一事件,只会执行一次函数

  • 实现原理设置一个定时器,约定在xx毫秒后再触发事件处理,每次触发事件都会重新设置计时器,直到xx毫秒内无第二次操作
  • 防抖常用于搜索框/滚动条的监听事件处理,如果不做防抖,每输入一个字/滚动屏幕,都会触发事件处理,造成性能浪费。

节流

防抖是延迟执行,而节流是间隔执行,函数节流即每隔一段时间就执行一次

  • 实现原理为设置一个定时器,约定xx毫秒后执行事件,如果时间到了,那么执行函数并重置定时器
  • 和防抖的区别在于,防抖每次触发事件都重置定时器,而节流在定时器到时间后再清空定时器

在公共的js文件utils.js中添加防抖函数如下

export default {
    debounce(func, delay = 300) {   //防抖, 默认300毫秒
        let timeout = null
        return function () {
            let context = this
            let args = arguments
            if (timeout) clearTimeout(timeout)
            timeout = setTimeout(() => { // 一直输入timeout一直有值,就一直clearTimeout(timeout)
              func.apply(context, args)
            }, delay)
        }
    },
   throttle(func, wait) { // 节流
      let timeout = null
      return function () {
          let context = this
          let args = arguments
          if (!timeout) {
              timeout = setTimeout(() => {
                  timeout = null
                  func.apply(context, args)
              }, wait)
          }
      }
  	}
}

输入框搜索,输入几秒后执行

 <input v-model="infos.name" @input='inputHandle' >
 <el-button @click="clickHandle">{{num}}</el-button>

页面调用

<script>
import unit from '../js/utils'
export default {
  name: 'index',
  data() {
    return {
      num: 0,
      infos: { // 表格参数
        name: '',
      },
    };
  },
  methods: {
    inputHandle: unit.debouncekkk(function () {
      console.log('防抖成功');
      let data = this.$post('Company/GetPage', this.infos); // 接口名称
      data = data.data;
      console.log('data', data);
    }, 5000),
    clickHandle: unit.throttle(function () {
      this.num++
      console.log(this.num);
    }, 5000),
    // inputHandle() {
    //   let a = unit.debouncekkk(function () { // this.debouncekkk(),把debouncekkk()方法写在这里面
    //     console.log(2222);
    //   }, 2000)
    //   a()
    // },
  },

};
</script>

func.apply(this, arguments);为何要这么写?

关键在第一个参数,为了确保上下文环境为当前的this,所以不能直接用fn。

请问为甚么你要确保 func 执行的上下文是this?在这个箭头函数里this又是指向的谁?

加上 apply 确保 在 inputHandle 函数里的 this 指向的是 input对象(不然就指向 window 了,不是我们想要的)。这里的箭头函数依旧是指向 input 对象。

不加apply时this是指向window的。因为 inputHandle 函数定义在全局中,所以调用时里面this指向window,所以才需要加上 apply,显示绑定 this 值(input对象)到 sayH 函数里面去