了解防抖和节流

304 阅读2分钟

了解防抖和节流的实现

    我们在前段界面的操作中,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,亦或者手抖多次点击了按钮等等;瞬间的操作都会导致这些事件会被高频触发,如果这些事情的回调函数比较负责的话,就会出现响应速度跟不上我们出发的频率;    防抖节流就是对上述情况的两种优化方案;

防抖

    首先设置个延迟时间,防抖和和节流的实现中会用到----time=3000ms,这个时间就是自定义的啦,根据实际情况定;

   防抖就是,对于一个很可能高频率被触发的事件,如果在3秒内没有被再次触发,那么就立即执行他,如果在3秒内又再次被触发的话,这个事件不会执行,再继续等一个3秒,再判断3秒内没有被再次触发,直到在给定的延迟时间内不被触发时就去执行这个事件;说着有点涩,写个示例瞅瞅;

场景:放置表单的按钮被重复点击,避免重复提交

    /* 防抖 */
    export const Debounce = (fn, time) => {
        let dTimer; // 定义全局
        return function () {
            /* 如果dTimer为真,则阻止setTimeout继续执行,因而dTimer没有办法被置为null(false),所以callNow一直为false,fn无法执行 */
            if (dTimer) {
                clearTimeout(dTimer)
            }
            // eslint-disable-next-line prefer-rest-params
            const agrs = arguments;
            const callNow = !dTimer;
            dTimer = setTimeout(() => {
                dTimer = null
            }, time)
            if (callNow) {
                fn.apply(this, agrs)
            }
        }
    }

然后在界面加个按钮调用下这个函数:

    <el-button type="primary" size="default" @click="fangDou">测试防抖</el-button>
    fangDou: Debounce(function () {
      console.log("防抖成功");
     }, 3000),

    效果为:这个按钮第一次点击时触发事件,以后的每次点击就做判断,如果在3秒内就不会触发,再次开始计时3秒,如果超过3秒后点击了一次按钮,那就触发这个事件。

loadingss.gif

节流

    节流比较好理解,就是在固定周期内,只执行一次动作,就比如这个提交按钮,指定的时间为3秒,当你在3秒内点击这个按钮十次,结果这个按钮只会触发一次,如果你你在10秒内点击了10次按钮,这个按钮会被处罚三次;


    /* 节流 */
    export const Throttle = (fn, time) => {
        let tTimer;
        return function () {
            if (tTimer) {
                return
            }
            // eslint-disable-next-line prefer-rest-params
            const args = arguments
            tTimer = setTimeout(() => {
                fn.apply(this, args)
                tTimer = null
            }, time)
        }
    }

同样的在界面中试试:

     <el-button type="primary" size="default" @click="jieliu">测试节流</el-button>
    jieliu: Throttle(function () {
          console.log("节流成功");
        }, 1000)

loadings.gif     图中就可以看到,我连续点击了很多次,但他就是按照那个延迟时间,每个1秒就执行一次,丝毫不管我手速有多快啊;