美文网首页
手写防抖函数 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