手写源码之--防抖节流函数

73 阅读1分钟

1,防抖函数

定义:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
例子:类似于生活中坐公交车,最后一个人上车后n秒再关车门,如果n秒内有人上车,则重新计时
使用场景:input框的输入搜索,浏览器的resize事件

<input type="text" name="in"/>
<script >
    /**
     * 防抖函数:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
     * @param fn 事件函数
     * @param delayTime 延迟时间
     * @returns {Function}
     */
   function debounce(fn, delay=500) {
        let timer;
        return function () {
            let  args = arguments
           if ( timer ){ clearTimeout( timer )}
            timer = setTimeout(()=> {
            	console.log(this)//谁调用就指向谁,此处为vue实例
                fn.apply(this, args);
            }, delay)
        }
    };
    var int = document.querySelector("input");

    function log() {
        console.log(this.value)
    }

    int.oninput = debounce(log, 1000);
</script>

2,节流函数

定义:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
例子:类似于连发狙击枪,就算一直按着射击键,也只能隔段时间射出一颗子弹
使用场景:降低事件触发频率,如用户连续点击提交按钮,鼠标的滚动监听

<script >
    let windowResize=function () {
        console.log(window.innerHeight);
    };
    window.addEventListener("resize",throttle(windowResize,1000));

    /**
     * 节流函数:间隔n秒触发一次
     * @param func
     * @param wait
     * @returns {Function}
     */
 function throttle(fn, wait = 500) {
    let prev = 0
    return function() {
    let args = arguments
    let now = Date.now()
    if (now - prev > wait) {
      console.log(this)//谁调用就指向谁
      fn.apply(this, args)
      prev = now
    }
  }
}
</script>

在vue项目中的使用

场景:一个向后台发起请求的查询按钮

1,将函数写在utils中
2, 页面引入
import { throttle,debounce } from '@/assets/Utils'
使用
 <a-button @click="getHistoryData(3)" >查询</a-button>
methods:{
  getHistoryData:debounce(function(n) {
        console.log(n)//这里可以使用传递的参数,因为debounce函数做了处理
        for (let key in this.chartData) {
          this.chartData[key].length = 0
        }
    }
}