JavaScript训练合集——防抖与节流

143 阅读4分钟

防抖与节流在面试中出现的频率可太高了,最基本的要求是知道概念,知道使用场景,知道实现方法。大部分的时候都是要求要直接手写的。。

防抖

概念及应用场景

防抖,就像它的名字一样,你可以把它粗俗的理解成,防止人手抖,误操作。 拿一个真实的场景举例,在商城中的首页一般都会有一个搜索框,用户可以根据自己的需求,来搜索想要的商品。 这个需求整体的处理逻辑是,前端接收用户填写的搜索内容,直接通过接口来传给后端,后端根据搜索内容查数据库,查到结果后返给前端,前端展示,这是一个最最基本,粗糙的处理逻辑。 但是,如果我开一个脚本连点器,一分钟搜索10000000000000次,你仍然按照这个逻辑来处理的话,什么样的服务器都得崩。 这时候就需要用防抖来优化逻辑,我们可以给用户的搜索事件限定一个时间间隔,比如2s,如果用户在2s内又触发了搜索事件,就等等,等他什么时候触发搜索事件的时间超过了2s,咱们再给他搜索。

这就是在真实的场景下的防抖的概念和应用。 官方介绍的术语是:

连续点击的情况下不会执行,只在最后一下点击过指定的秒数后才会执行。应用场景有:点击事件,输入框搜索,词语联想。

实现原理及代码应用

它实现的原理比较简单,就是通过定时器来实现。

function debounce(fn, delay) {
    let timeout = null;
    return function() {
        // 每一次点击判断有延迟执行的任务就停止
        if(timeout !== null) clearTimeout(timeout);
        // 否则就开始延迟任务
        timeout = setTimeout(fn, delay);
    }
}

我们可以怎么样来使用它呢,比如我们现在有一个按钮。

let oBtn = document.getElementById('btn');

点击一下,输出一个 ' 微信公众号 : Code程序人生 ' 。

function sayDebounce() {
    console.log("微信公众号 : Code程序人生! ");
}
oBtn.addEventListener("click", debounce(sayDebounce, 1000));

这样就实现了对这个点击事件的防抖处理。

节流

概念及应用场景

节流,其实它的作用也与它的字面意思基本一致。在一定条件下,限制某件事情出现的频率,这就是节流。

仍然拿商城中的搜索框举例,虽然这个不太现实,不太可能用人对商城的搜索框节流,但是话糙理不糙,能理解意思就可以。

如果我们的服务器资源很有限,要限制用户使用搜索框的频率,这个时候我们就需要用到节流,大概的处理逻辑就是,比如在1分钟的时间里,我只允许用户使用一次搜索框,这其实就是节流。

官方介绍术语 :

频繁触发的时候,比如滚动或连续点击,在指定的间隔时间内,只允许执行一次。应用场景:点击按钮,监听滚动条,懒加载等

实现原理及代码应用

它的原理是什么呢,依然是定时器。

它在具体的代码实现上与节流有比较不同的一点是,它在实际的应用场景中,对于第一次事件的处理是可以不一样的,可以从第一次就进行节流限制频率,也可以第一次事件立即执行,第二次再进行节流,它们都有不同的应用场景。

// 方案一 连续点击的话, 每过 wait 秒执行一次
export function throttle(fn, wait) {
    let bool = true;
    return function() {
        if(!bool) return;
        bool = false;
        setTimeout(() => {
            // fn() // fn中this指向window
            fn.call(this, arguments); // fn中this指向btn, 下面同理
            btn = true;
        }, wait);
    }
}
// 方案二 连续点击的话, 第一下点击会立即执行一次, 然后每过 wait 秒执行一次
export function throttlePlus(fn, wait) {
    let date = Date.now();
    return function() {
        let now = Date.now();
        // 用当前时间 减去 上一次点击的时间 和 传进来的时间作对比
        if(now - date > wait) {
            fn.call(this, arguments);
            date = now;
        }
    }
}

它的应用依然可以由一次点击事件引出。

 let oBtn = document.getElementById('btn');

function sayThrottle() {
    console.log("微信公众号 : Code程序人生");
}

oBtn.addEventListener("click", throttlePlus(sayThrottle, 1000));

ok,如果你可以理解我上面这些内容,那么应付你的面试应该没有多大问题,有问题欢迎加联系方式交流!