现在,先忘了 "函数防抖" 和 "函数节流" 吧

6,354 阅读3分钟

前言

一开始接触这两个概念的时候,并不是十分明白这两个单词的语义,也不清楚到底这是干什么用的。相信很多人也跟我一样,如果没有的话,那就尴尬了。

声明:这个标题的意思是想让大家忘掉概念,从业务场景上介绍在什么样的情况下可以怎样做,不被这两个术语纠结住,不为了学而学。 并不是让你忘记这两个概念对应的实质内容,没必要纠结忘不忘。

函数防抖

暂时忘掉函数防抖。

先有需求再有解决方案,先来描述一个简单的业务场景:

现在要实现一个文章云端缓存功能,如果用户每输入一个字符就调用接口同步缓存一次的话,这样服务器的压力会比较大。

而且多个接口顺序发送出去,服务端不一定是按照这个顺序收到的,可能会导致储存的内容并不是最新的内容。

这时候,就需要选择一个时机去调用接口而不是每次都调用,这个时机可以选择在用户停止输入的时候。

那我们怎么知道用户已经停止输入了呢?

如果N秒内输入框的内容没有发生改变,我们就可以认为用户停止输入或者暂停输入了。

    let timer;
    const input = document.querySelector('input');

    input.addEventListener('input', function() {
        clearTimeout(timer);
        timer = setTimeout(function() {
            // 执行具体代码
        }, 500)
    })

看演示:

据观察,在掘金发布文章的时候,自动保存至草稿的功能也是类似的实现方法,大家可以试试

函数节流

暂时忘掉函数节流。

再来描述一个简单的业务场景:

现在要实现一个点赞的功能,某个用户发布了一个动态,大家可以给他无限点赞,也就是说每个点赞后端都要记录下来。理论上来讲用户每点赞一次调用一次接口即可。但是同样的,和上面一样,这样对服务器的压力会比较大。

无限点赞是指,用户的每个点击都是一个有效的赞,是需要累计的。可以理解为我们要做一个点赞排行榜,根据每个用户的点赞数排序。

这时候,我们可以通过限制频率的方式来缓解这个情况,比如说点击按钮后300毫秒后再调用接口,在这300毫秒期间所有的点击都会被累计。

    // 点赞数
    let likes = 0;
    // 定时器标识
    let timer;
    
    /*
    * 用户点赞函数
    * */
    function clickButton() {
        likes++;
        
        if ( timer ) return;
        
        timer = setTimeout(() => {
            // 执行网络请求
            // ajax...
            
            // 点赞数重置
            likes = 0;
            
            // 重置timer
            timer = null;
        }, 300)
    }

看演示:

总结

类似于这种处理某些情景下的技术方案,对于术语并不是很重要,这基本上只对于沟通上大家都知道在说啥。

关键是先清楚为什么要这么做。