使用防抖与节流,及this指向问题

  • A+
所属分类:系统文档

最近项目中遇到了防抖与节流问题,搜索了很多文章都有this指向的问题,最后不得不采取一种很low的方法

data中定义isFirst为1

if (this.isFirst < 2){
    this.isFirst = 2
    setTimeout(() => {
        this.isFirst = 1
      }, 1000)
  }

javascript

这样就形成了假的节流

但是我们怎么能屈服于这种写法

继续探索vue项目中用闭包的方式防抖节流
一顿操作后

 const delay = (function () {
    let timeout
    return (callback, ms) => {
      if (timeout) clearTimeout(timeout)
      let callNow = !timeout
      timeout = setTimeout(() => {
        timeout = undefined
      }, ms)
      if (callNow) callback.apply(this, [callback, ms])
    }
  })()
 export default {
    methods: {
        delay(() => {
          // do something
       }, 1000)
    }
}
javascript

用了立即执行的函数方法,就能够获取到全局的this了

使用防抖函数所遇见的坑

以前的防抖和节流都是在js中直接书写,后使用vue进行组件化开发之后,有些地方需要注意。

正常写法

    function debounce(func, delay) {
      let timeout
      return function () {
        let context = this;
        let args = arguments;
        if (timeout) {
          clearTimeout(timeout)
        }
        timeout = setTimeout(() => {
          func.apply(context, args)
        }, delay)
      }
    }
javascript

使用

    function change(volume, data) {
      debounce(() => {
        console.log('change', volume, data);
      }, 500)
    }
javascript

Vue中写法使用

注意: Vue中使用时,需要定义timeout,同时在防抖函数中,this的指向发生了变化,需要在return之前获取vue实例。这个时候,你直接使用,还是不行的,只要debug就会发现debounce返回的func没有进去,需要手动执行一下(添加括号)。

  data() {
    return {
      timeout: null
    }
  }
javascript
    change(volume, data) {
      this.debounce(() => {
        console.log('change', volume, data)
      }, 500)
    },
    debounce(func, delay) {
      let context = this // this指向发生变化,需要提出来
      let args = arguments
      return function () {
        if (context.timeout) {
          clearTimeout(context.timeout)
        }
        context.timeout = setTimeout(() => {
          func.apply(context, args)
        }, delay)
      }()// 注意:我加了()
    }
javascript

Vue中的watch的防抖简写

    watchObj: {
      handler(val) {
        let _this = this
        clearTimeout(this.timeout)
        this.timeout = setTimeout(() => {
          _this.handlerData(val)
        }, 500)
      }
    }
javascript
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin