函数防抖&函数节流

什么是节流和防抖

  • debounce(防抖)的作用是在让在用户动作停止后延迟 x ms 再执行回调。
  • throttle(节流)的作用是在用户动作期间每隔一定时间(如 200ms)执行一次回调。

如何理解

防抖

如果有人进电梯(触发事件),那电梯将在 10 秒钟后出发(执行事件),这时如果又有人进电梯了(在 10 秒内再次触发该事件),我们又得等 10 秒再出发(重新计时)。

节流

游戏中人物的技能 CD,当技能处于闲置状态时,按下技能键(触发事件)能立马生效(执行事件)。生效后有技能冷却时间,期间不管你按多少下技能键(触发事件),就算把键盘按爆,都无法再次触发技能,直到冷却完毕。

P.S. CD 时间:Cool Down Time

应用场景

防抖

  1. 表单提交按钮的连续点击,防止重复提交。比如重复发送一篇文章。
  2. 搜索查询(连续输入文字后发送 AJAX 请求进行验证,(停止输入后)验证一次就好)
  3. 滚动事件 scroll(只需执行触发的最后一次滚动事件的处理程序)

节流

  1. 自动保存草稿功能,当用户在输入的时候(一直触发事件),单位时间内只保存一次草稿。
  2. 上拉加载更多,防止用户暴力快速上滑。隔一段时间才能触发一次
  3. 滚动事件 scroll,(只要页面滚动就会间隔一段时间判断一次)

代码实现

防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @description: 防抖函数:函数被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时
* @param {Function} fn 要执行的函数
* @param {Number} delay delay毫秒后执行回调
*/
function debounce(fn, delay = 500) {
let timer = null;
// 为了封装,这里使用了闭包来保存局部变量=>tip: 闭包保护的变量会一直保存在内存中但又不会 “污染” 全局的变量
return function () {
const context = this;
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, arguments);
timer = null;
}, delay);
};
}

节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* @description: 节流函数:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行
* @param {Function} fn 要执行的函数
* @param {Number} gapTime 单位时间
*/
function throttle(fn, gapTime = 500) {
let canUse = true;
return function () {
if (canUse) {
fn.apply(this, arguments);
canUse = false;
setTimeout(() => (canUse = true), gapTime);
}
};
}

示例

参考来源