防抖与节流的原理和实现

338 阅读2分钟

一、防抖

1. 什么是防抖?

​ 防抖就是相当于游戏里的魔法师的读条技能,只有当读条结束技能才会释放出来,当读条读到一半的情况下被打断施法就需要重新读条,所以读条技能你狂按是没用的,只会把最后按的那下释放出来,防抖也是如此。

2.防抖的实现方式

​ 根据上述防抖概念,防抖的实现只需要识别上一次激发的技能(事件)有没有放出来,如果没有就把上一次的施法(定时器)取消掉,重新触发新的读条;如果上一次的技能经过了读条释放完了,那么这次就正常读条等待技能释放就行了。

# 代码实现

function debounce(fn, wait) {
    let timeout = null;
    return function(...args) {
        if(timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, args);
        }, wait);
    }
}

// 上面的核心代码,下面的调用演示一下

function handle(x) {
    console.log(x); 
}

let click = debounce(handle, 1000);

click("hello");
click("hello");
click("hello");
click("world");

# 输出的结果

一秒钟后输出 “world”,因为在读条阶段重新触发事件,输出 “hello” 的事件被取消掉了。

二、节流

1.什么是节流?

​ 节流和防抖有点相近却又不同,节流不像魔法师,节流像一个冲锋枪,而且是连发的,大家都知道你扣住冲锋枪的扳机扫射的时候它不可能让子弹一个一个的挨在一起打出去,都会有一个时间间隔。

​ 节流就是如此,比如你每一毫秒击发一次,子弹都不够你打的,打出去也是浪费,就需要节流,让你依旧保持,每毫秒击发一次的手感,但是控制子弹每 100 毫秒打出去一个,在时间间隔内的其他击发都被无效化了,以此来实现了节流。

# 代码实现

let throttle = function(func, delay) {
    let run = true;
    return function(...args) {
        if (!run) return;
        run = false;
        setTimeout(() => {
            run = true;
            func.apply(this, args);
        }, delay);
    }
}

// 上面的核心代码,下面的调用演示一下

function handle() {
    console.log(Math.random());
}

let click = throttle(handle, 1000);

let interval = setInterval(() => {
    click();
}, 10);

setTimeout(() => {
    clearInterval(interval);
}, 10000);

# 输出的结果

每隔一秒钟输出一个随机数,虽然他每隔10毫秒就触发了一次。