[前端基础]最后一次看:节流&防抖
节流
-
节流定义
节流英文throttle, 各工具库函数基本统一使用throttle命名。 节流 顾名思义 就是限制流量。 比如马路上的车流量; 如果连续有很多车量申请通过高速路口, 但是高速路口的规定就是1s只允许通过1辆车, 那这就是节流。 即 规定时间内,某函数只允许触发1次,即便有多次调用。适用场景: 函数被频繁调用的场景 如 window.onresize() 事件、window.onscroll() 事件、mousemove 事件、上传进度等情况
-
原理与实现
实现方案有2种:
1、原理:利用计时器 计算此次调用与上次函数执行时的时间差, 超过设定间隔则执行,不然就算了。
实现:
const throttle = (fn, wait = 100) => {
let previous = 0;
return function(...args) {
let now = +new Date();
if (now - previous > wait) {
previous = now;
fn.apply(this, args)
}
}
}
效果:

分析:绑定在 mousemove 上的事件, 经过 throttle 调用。 此实现方式为开始即触发, 但最后不会触发(看上图的最后部分)
2、原理: 初次调用函数,函数直接执行,执行后设置一个定时器,指定下次执行时机; 下次函数调用,如果发现有定时器,就算了...
实现:
const throttle = (fn, wait = 50) => {
let timer = null;
return function(...args) {
if (timer) return;
fn.apply(this, args)
timer = setTimeout(() => {
timer = null;
fn.apply(this, args)
}, wait);
}
}
效果:

分析: 绑定在 mousemove 上的事件, 经过 throttle 调用。 此实现方式为开始即触发, 但最后也会触发(看上图的最后部分)
防抖
-
防抖定义
防抖英文debounce, 各工具库函数基本统一使用debounce命名。 防抖 顾名思义 就是防止抖动。 比如想给博主点赞,使用外挂手速很快,每秒最高可点10000 下, 那这就对其他博主很不公平,就要进行限制,规定只要你连续点,只有当你最后那次才有效,那这就是防抖。 即 函数防抖 debounce 指的是某个函数在某段时间内,无论触发了多少次,都只执行最后一次。
适用场景: 表单提交、邮件发送、下单等操作,防止「手滑」重复提交 -
原理与实现
1、原理:利用定时器设定经过多少时间触发,持续调用 就重新计时。
实现:
function debounce(fn, wait = 50) {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}
效果:

分析: 绑定在 mousemove 上的事件, 经过 debounce 调用。 此实现方式为开始不触发, 停止mousemove 后经过指定时间触发(看上图的最后部分)
2、 上面实现方式的效果是 持续触发都不会进行函数调用,只有停止时才调用, 那如果 想开始就立即调用呢?
实现:
function debounce(fn, wait = 50) {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
if (!timer) {
fn.apply(this, args)
}
timer = setTimeout(() => {
timer= null;
fn.apply(this, args)
}, wait)
}
}
效果:

防抖&节流

Lodash & underscore
Lodash & underscore 工具库都有对 这两个函数的实现, 其功能更加完善,代码更健壮。 其中包含功能为{leading: boolean; trailing: boolean} , 即 这两个开关分别控制是否需要响应事件刚开始以及最后的那次调用。
参考文档:
1、demo code(文中的测试代码来源)
2、throttle & debounce
3、Lodash
hi 要走了么,点赞了嘛