前言

根据我以往的面试经验来看,防抖与节流基本是必考题了。可惜我以前并不是很重视这两个概念。

我记得当时是这样回答的。

笔者以往回答

防抖和节流是为了防止用户重复点击而衍生的两个概念,我不知道这两个概念是什么意思。但是我可以告诉你如何防止用户重复点击。可以采用… (省略)

基础

各位也看到了,回答的不是很好。面试官肯定觉得我这个人对理论不重视。这样肯定不行,所以我决定写一篇博客,从基础概念开始讲。这也算对自己的一种负责。

防抖

如果一个函数在短时间内疯狂执行,但是我们希望在最后一次触发结束时隔一段时间再执行该函数。由此而衍生的算法就叫防抖。

节流

如果一个函数在短时间内疯狂执行,但是我们希望在一段时间内只执行一次,即第一次触发函数的延时结束时再执行。由此而衍生的算法就叫节流。

进阶

从基础篇里面我们已经学到了防抖和节流的基础概念。接下来我们来学一些进阶知识

防抖的应用场景

当用户在input标签里疯狂输入值,而此同时我们只打算取最后一次输入的值

防抖的作用

现在我们已经知道防抖的定义和应用场景。

现在该谈论一个严肃的问题。防抖的作用是什么。

我们拿oninput事件举例。如果不存在防抖算法,那么只要用户输的足够快,就会不停的调oninput的回调函数。那么问题来了,如果oninput的回调函数需要调后台接口该怎么办呢?那岂不是0.5s或是更少就调一次接口?而且没有输入完成,真的有必要调后台接口吗?

答案显然是否定的。

防抖的作用就是为了不造成不必要的流量损失,从而提高用户界面的流畅度。

节流的应用场景

向下滑动请求后台接口,且滑动十分频繁。

节流的作用

节流的应用场景包含移动端页面的向上滑动无限加载,这个时候我们应该只取第一次的请求结果。所以需要隔一段时间,即第一次请求结果完成后的一段时间再执行第二次函数。

节流的作用也是为了不造成不必要的流量损失,从而提高用户界面的流畅度。
防抖与节流展示

笔者将奉献防抖与节流算法给各位看官

防抖

function debounce(fn,delay,...arg){
    let timer = null // 借助闭包
    return function() {
        if(timer){ 
        // 防抖算法会在最后一次触发结束时隔一段时间再执行该函数
        // 所以多了这层判断
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay,...arg)
    }
}
// 实际应用
// fn是scroll的回调函数,写滚动条事件的逻辑
window.scroll = debounce(fn,1000)

节流

function throttle(fn,delay,...arg){
    let valid = true
    return function() {
       if(!valid){
           // 节流算法会在第一次触发函数的延时结束时再执行
           return false 
       }
        valid = false
        setTimeout(() => {
            fn(...arg)
            valid = true;
            //第一次触发函数的掩饰已结束。进入新一轮
        }, delay)
    }
}
// fn是scroll的回调函数,写滚动条事件的逻辑
window.onscroll = throttle(fn,1000)