防抖与节流

156 阅读2分钟

“持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

防抖与节流

防抖:

 let telIn = document.querySelector("input");
        telIn.addEventListener("input", shake(demo, 2000))

        //将防抖包装成一个方法,接受两个参数 一个是函数 另一个是处罚的时间间隔

        function shake(fn, wait) {
            let timeOut = null;
            return args => {
            //判断是否已经触发 
                if (timeOut) clearTimeout(timeOut)
                timeOut = setTimeout(fn, wait);
            }

        }
        function demo() {
            console.log('发起请求');
        }

节流:函数节流指的是某个函数在一定时间间隔内(例如2秒内)只执行一次,在这2秒内 无视后来产生的函数调用请求,也不会延长时间间隔。2秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的2秒内依旧无视后来产生的函数调用请求,以此类推。 原理及实现:节流用于函数被频繁地调用场景,比如表单提交、鼠标移动、上传进度的情况。

实现的方案有两种:

  1. 第一种:利用时间戳判断是否到达执行时间,记录上次执行的时间戳,然后每次触发事件执行回调函数,用回调判断当前的时间和上次执行的时间戳是否达到时间差,如果是就执行,并且重新更新时间戳,以此循环下去。
  2. 第二种:利用定时器,设置定时器,每隔几秒钟触发事件,直到事件触发过后,重新设置定时器。 下面采取第一种方法实现:使用闭包保存一个变量。触发throttle函数的时候判断时间差,如果小宇等待的时间,则不触发事件,如果大于等待的时间就重新设置timeOut并且执行函数fn。
const throttle = (fn, wait = 1000) => {
            // 上一次执行 fn 的时间
            let timeOut = 0
            // 将 throttle 处理结果当作函数返回
            return function (...args) {
                // 获取当前时间,转换成时间戳,单位毫秒
                let time = +new Date()
                // 将当前时间和上一次执行函数的时间进行对比
                // 大于等待时间就把 timeOut设置为当前时间并执行函数 fn
                if (time - timeOut > wait) {
                    timeOut = time
                    fn.apply(this, args)
                }
            }
        }

        // 执行 throttle 函数返回新函数
        const betterFn = throttle(() => console.log('fn 函数执行了'), 1000)
        // 每 10 毫秒执行一次 betterFn 函数,但是只有时间差大于 1000 时才会执行 fn
        setInterval(betterFn, 10)

总结:如果只关心最终状态,建议使用防抖。如果是想要函数以可控的速率执行,那么建议使用节流。 防抖:防止抖动 节流:节省交互沟通