防抖和节流 (简单易懂版)

序言

"什么是防抖? 什么是节流?"

在学习这两个知识点的时候总是会容易搞混哪个是防抖,哪个是节流。

其分别又代表着什么含义,对于在不同的开发需求中如何合理的运用这两个知识点尤为重要。

一、防抖

防抖,顾名思义就是"防止抖动"。

放在按钮的点击事件中即指: 在指定的时间内,你在不停的点击按钮,按钮所绑定的事件处理函数只会在最后一次执行。

也就是当你点击完按钮后,在指定时间内没有再次触发这个按钮的点击,则当指定的时间到了之后,事件的处理函数也就会执行。

假如有一天中午你刚在工地搬完二十车的砖头,你隐约听到了汽车的鸣笛声。

是它来了,运钞车。它承载着你这一年的辛劳和泪水,今天是发工资的日子。

忙碌了一上午,你的双手已经疲惫不堪,你不缓不慢的放下了手上的二十块砖头。

走向了那堆满钞票的队伍前,等待着领取那属于你的劳动成果。

随着时间的流逝,轮到你了。工头指着那一堆说,那堆是你的。

你用手臂拂去额头的汗水,憨笑道:"诶,好嘞!",然后你拿起桌上的签字笔准备签署。

当你正想签名的时候,你的手臂不知觉的抖动了起来,你知道,这种状态下是没办法签字了。

你的双眼凝视着你的手臂,它还在不停的抖动。你的眼角泛起了一丝轻蔑:"呵!防抖, 不过尔尔!"

然后,嘴中默念道:

// 简易防抖函数
function debounce(fn, delay) {
  let timer = null;
  return function() {
    if (timer) {
      clearTimeout(timer);
      timer = setTimeout(fn, delay);
    } else {
      timer = setTimeout(fn, delay);
    }
  };
}

// 以下为示例代码:
// 签名
function signature(){
   document.write('张三')
}

// 调用防抖函数
debounce(signature, 3000)()

时间一秒,两秒,三秒...终于!它停止了...

你以迅雷不及掩耳耳之势,潇洒的签上了你的大名----"张三"。

二、节流

节流,顾名思义就是节约流水

放在按钮的点击事件中即指: 在指定的时间内,你还是在不停的点击按钮,按钮所绑定的事件处理函数只会执行一次。

换成技能的冷却时间可能会更好理解些:你点击某个技能之后它会进入冷却,在冷却期间无法再次触发这个技能。

时间回到你签完名字时的前二十分钟。

你放下砖头之后,看了看满是砖土的双手,又看了看不远处的水龙头,叹息道:"怎么又停水了..."

你略作思考,便朝着工地对面的公厕走去。

来到公厕门口,你看到一名约是九岁左右的孩童在洗手池中玩耍。你略微皱眉,快步走上前去。

当你正要斥责孩童的不懂事的时候,那名孩童先于你开口说话了。"你可知,何谓节流?"

你一头雾水的走过来,心中奇怪这孩童怎地在此处玩耍还爱自言自语?

待你走近,方知原来孩童玩耍的水池中并无水迹,便开始怀疑公厕是不是也停水了。

正当你还在疑虑之中时,孩童又说话了。"我知道哪里有水,但阁下须回答我一个问题"

"什么问题?"

"何谓节流?"

"不知,还望赐教",你再次皱起了眉头,稍加思索后答道。

"谓之节流,即节约流水。"

"隔壁这个水池的水龙头是好的,你且洗着手并听我道来"

(你的内心):"Hai..."

"就像这个带感应功能的水龙头一样,手放上去之后水龙头就会释放水流出来,但是当过几秒后水流就会停止"

"这就是节约流水,你把手再放上去,水流亦会再次被释放"

"你在几秒内来回将手放在感应器上,水流并不会随之快速释放/暂停,大体相似于此:"

// 简易节流函数
function throttle(fn, delay) {
    let valid = null;
    return () => {
    if (valid) {
        return false;
    }
    valid = true;
    setTimeout(() => {
        fn();
        valid = false;
    }, delay);
    };
}

// 以下为代码示例
// 释放流水
function releaseWater() {
  return "水"
}

// 调用节流
throttle(releaseWater, 1500)()

听到这里,你仿佛犹如醍醐灌顶,转瞬便明白了其中门道,顺便还请教了下什么是"防抖"。

总结:

①防抖:指定时间内,多次操作只取最后一次操作

②节流: 指定时间内,多次触发操作只会执行第一次

节流和防抖都有很多种,比如下面的立即执行版节流,但是万变不离其宗,知道核心原理便可以一法通时万法通

// 节流 - 立即执行版
function throttleRightNow(fn, delay) {
    let valid = null;
    return () => {
    if (valid) {
        return false;
    }
    valid = true;
    fn();
    setTimeout(() => {
        valid = false;
    }, delay);
    };
}

原文地址:https://www.cnblogs.com/ViavaCos/p/13835305.html