美文网首页
手写防抖函数 debounce 和节流函数 throttle

手写防抖函数 debounce 和节流函数 throttle

作者: 小棋子js | 来源:发表于2021-05-22 10:25 被阅读0次

    防抖和节流又是什么东西?

    用来处理某个工作短时间内过于频繁触发的场景,只是根据不同的处理方式有不同的说法。
    应用场景:防止用户连续多次点击提交表单、监听滚动、窗口大小、输入框内容校验等高频事件

    简要概念:

    节流 即在一个事件被连续的触发过程中,以一个固定的时间长度,间隔的去执行一个函数;
    防抖 即在一个事件被连续的触发过程中,只在最后一次触发时执行一个函数

    防抖:某个函数在短时间内只执行最后一次。

    意思也就是说,函数被触发时,需要先延迟,在延迟的时间内,如果再次被触发,则取消之前的延迟,重新开始延迟。这样就能达到,只响应最后一次,其余的请求都过滤掉。

    这种处理方式有很多实际的应用场景:比如对输入框数据的校验处理,没必要每输入一个字符就校验一遍;

    节流:某个函数在指定时间段内只执行第一次,直到指定时间段结束,周而复始。

    跟防抖不一样的是,节流是指定时间段内只执行第一次,也就是这段时间内,只需要响应第一次的请求即可,后续的请求都会被过滤掉,直到下个时间段,重新来过,周而复始。

    应用场景:Android 里的屏幕刷新机制,每个帧(16.6ms)内,不管进行了多少次请求界面刷新的操作,只需响应第一次的请求,去向底层注册监听帧信号即可。因为接收到帧信号后,是通过遍历 View 树来刷新界面,所以注册的动作只需要进行一次就够了。Vue 的虚拟 DOM 的刷新也是类似的机制。

    写一个utils.js:

    /*
    * 自己写一个防抖函数吧 (注意维护同一个timer)
    * */
    防抖代码
    export function debounce(fn, delay) {
      var timer = null;// //定义一个变量作为等会清除对象;记录上一次的延时器
      return function() {
        var args = arguments;
        var that = this;
        clearTimeout(timer) // 清除上一次延时器
        timer = setTimeout(function() {
            fn.apply(that,args)
        }, delay);
      }
    }
    /*
    * 自己写一个节流函数吧
    * */
    export function throttle (fn, delay) {
      let clickNow = true
      return function () {
        if (clickNow) {
          clickNow = false
          setTimeout(function () {
    //为什么要通过 apply 这种修改函数内部 this 的方式来调用原函数?直接 fn() 不行吗?
    //这里之所以要通过 call 方式来修改原函数的 this,
    //是因为,原函数通过参数进行传递时,是只会被当做普通函数处理,不管原函数本来是否挂载在某个对象上。
    //所以,如果 debounce 内部直接以 fn() 方式调用原函数,会导致原函数的内部 this 指向发生变化。
    //这边执行了节流函数fn()
            fn.apply(this, arguments)
            clickNow = true
          }, delay)
        }
      }
    }
    

    使用:

        clickFn: throttle(function () {
          console.log('节流测试')
        }, 1000),
    

    vue中使用防抖例子

    搜索排版代码

    <input type="text" placeholder="输入用户名" v-model="userName" v-on:input="userSearch">
    

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

    export default {
       debounce(fn, delay) {
         var timer = null;// //定义一个变量作为等会清除对象;记录上一次的延时器
         return function() {
           var args = arguments;
           var that = this;
           clearTimeout(timer) // 清除上一次延时器
           timer = setTimeout(function() {
              fn.apply(that,args)
           }, delay);
         }
       }
    }
    

    防抖搜索功能

    import utils from "@/js/utils";
     
    export default {
     
        methods: {
            //使用防抖函数
            uaerSearch: utils.debounce(function() {
                this.$axios.get('接口',this.userName).then(res=>{})
             },200)
        }
     
    }
    

    相关文章

      网友评论

          本文标题:手写防抖函数 debounce 和节流函数 throttle

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