防抖与节流

186 阅读2分钟

防抖(debounce) : 某一高频事件被触发时,只在最后一次触发执行函数

    function debounce(fn, delay) {
        // fn是你要调用的函数,delay是防抖的时间
        // timer是一个定时器
        let timer = null;
        // 返回一个闭包函数,用闭包保存timer确保其不会销毁,重复点击会清理上一次的定时器
        return function () {
            // 保存事件参数,防止fn函数需要事件参数里的数据
            let arg = arguments;
            // 调用一次就清除上一次的定时器
            clearTimeout(timer);
            // 开启这一次的定时器
            timer = setTimeout(() => {
                // 若不改变this指向,则会指向fn定义环境
                fn.apply(this, arg);
            }, delay)
        }
    }
    

throttle节流:某一高频事件被触发时,确保在每一个规定的时间段内执行函数

适用范围:浏览器下滑调接口

方法一:时间戳 首节流

function throttle(fn, delay = 1000) {
            // 记录第一次的调用时间
            var prev = null;
            console.log(prev);
            // 返回闭包函数
            return function () {
                // 保存事件参数
                var args = arguments;
                // 记录现在调用的时间
                var now = new Date().getTime();
                console.log(now);
                // 如果间隔时间大于等于设置的节流时间
                if (now - prev >= delay) {
                    // 执行函数
                    fn.apply(this, args);
                    // 将现在的时间设置为上一次执行时间
                    prev = now;
                }
            }
        }

方法二:(定时器版:尾节流)


        function throttle(fn, delay) {
            // 重置定时器
            let timer = null;
            // 返回闭包函数
            return function () {
                // 记录事件参数
                let args = arguments;
                // 如果定时器为空
                if (!timer) {
                    // 开启定时器
                    timer = setTimeout(() => {
                        // 执行函数
                        fn.apply(this, args);
                        // 函数执行完毕后重置定时器
                        timer = null;
                    }, delay);
                }
            }
        }

节流 : 首尾各执行一次

function throttle(fn, delay = 1000) {
            // 记录第一次的调用时间
            var prev = null;
            console.log(prev);
            // 返回闭包函数
            return function () {
                // 保存事件参数
                var args = arguments;
                // 记录现在调用的时间
                var now = new Date().getTime();
                console.log(now);
                // 如果间隔时间大于等于设置的节流时间
                if (now - prev >= delay) {
                    // 执行函数
                    fn.apply(this, args);
                    // 将现在的时间设置为上一次执行时间
                    prev = now;
                    setTimeout(() => {   // 尾执行
                        console.log("尾执行");
                        fn.apply(this, args);
                    }, delay)
                }
            }
        }