『 每日一题』手写每日一题之节流

1,022 阅读3分钟

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

大家好,在上一节中我们学习了函数防抖,今天我们继续来写每日一题。大家都知道防抖节流是一对好基友,因此今天我们就继续来学习如何在面试中手写节流函数

我们还是先来了解一下什么是节流,以及为什么要实现这个函数,只有知道了具体的原因,实现起来才有思路。

简单来说,节流就是限制一个函数在一定时间内只能执行一次

为什么要有这样的设定呢?我们来列举一个场景。在实际的开发中,我们经常会用到表单的提交,如果不添加提交的限制,当数据还没提交成功时,可能会导致用户反复多次重复点击提交按钮,这时候我们就可以通过函数节流来限制用户频繁提交的操作。

函数节流的目的是为了限制函数一段时间内只能执行一次,因此我们依旧需要借助 setTimeout 这个定时器来实现相关的功能。

函数节流:在延时的时间内,如果方法被触发,则直接退出方法, 从而实现一段时间内只执行一次。

有了上述关于函数节流相关的描述,接下来我们就可以来手写这个方法了,相关的代码如下:

/*
 * fn 需要执行的函数
 * delay 需要延时执行的时间,默认500毫秒
 */
const throttle = (fn, delay = 500) => {
    // 首先还是定义一个存储定时器的变量
    let timer = null;
    // 返回一个匿名函数
    return function() {
        const _self = this;
        // 判断当前是否已经存在定时器,如果存在则直接返回,不继续执行后续的代码
        if (timer) return;
        // 重新执行当前的函数
        timer = setTimeout(() => { 
            fn.apply(_self, arguments);
            timer = null;
        }, delay)
    }
};

在上述代码中,我们根据前面对函数节流的描述实现了相关的功能,主要注意一点,当定时器已经存在时,则不继续往下执行,而函数防抖是当定时器存在时,清除当前的定时器,重新再执行一次新的定时器,这是函数节流函数防抖的唯一区别,只需要记住这一点,就可以在面试中同时实现这两个手写方法。

实现了函数节流,我们依旧需要知道在实际开发中该如何使用,我们还是来举一个实际的例子,代码如下:

function testThrottle(e) {
    console.log(e);
}
var testThrottleFn = throttle(testThrottle, 1000); // 节流函数
document. = function (e) {
    testThrottleFn(e, 'throttle'); // 给节流函数传参
}
document.addEventListener('mousemove', debounceFn);

在实际开发中,我们给 document 绑定一个 mousemove 事件,如果不添加函数节流,当我们移动鼠标时,会频繁的执行,同样的数据会反复的获取,而我们希望获取到的并不是同样的数据,而是一定时间内获取一次,这样可以降低浏览器的计算,因此还是很有必要使用函数节流来做限制的。

同样在著名的 loadsh 库中,也实现了函数节流,大家如果有兴趣的,也可以到 loadsh 官网去看一下具体的实现原理,与我们上述的实现原理类似。不过我们自己写的肯定多多少少不会那么完善,因此也只有在面试中才会这么写,实际开发中还是用这些第三方库会更好一些。

最后,还是那句话,面试是面试,工作是工作。不要把面试中手写的代码用到实际的工作中,这样或多或少是会踩坑的。