前端面试系列:实现节流函数(throttle)

57 阅读1分钟

节流函数也是为了优化用户体验而诞生的一种技术手段,目的是为了限制事件处理函数一段时间内只能执行一次。注意了,它跟防抖函数有很大的区别:防抖函数是最后才执行一次事件处理函数,而节流函数是一段时间内就触发一次。

应用场景

  • 滚动加载页面数据
  • 其他需要限制事件处理函数执行频率的场景

技术原理

利用了闭包的技术原理

代码实现

function throttle(fn, delay) {
    // last: 上一次触发fn函数的时间;timer: 定时器
    let last, timer;
    return function () {
        let ctx = this; // 当前函数的执行上下文
        let args = arguments; // 当前函数的参数
        let now = Date.now(); // 当前函数执行时的时间
        if (last && now < last + delay) {
            // 如果当前函数触发时的时间间隔,小于用户指定的时间间隔,则不会执行fn事件处理函数
            if (timer) return
            // 设置定时器的目的是为了最后执行一次fn事件处理函数
            timer = setTimeout(function () {
                last = Date.now();
                timer = null;
                // 把args参数传递到fn函数,并且把fn函数的this指针指向ctx
                // 相当于ctx.fn(args)
                fn.apply(ctx, args);
               
            }, delay)
        } else {
            last = now; // 更新fn函数被执行时的时间
            if (timer) {
                // 清除定时器
                clearTimeout(timer)
                timer = null
            };
            // 事件会立即执行,之后每间隔 delay 毫秒执行一次
            fn.apply(ctx, args);
        }
    }
}

测试用例

function test(arg) {
    console.log(arg, 'arg')
}

const cb = throttle(test, 200);
window.onscroll = function() {
    console.log('window onscroll')
    cb.call(this, 'throttle test')
};

通过不断的滚动页面,我们在控制台中可以观察到 test 函数一开始先执行了一次,之后每间隔 200ms 重新执行一次。