前言
听说你还不会前端面试中常考的“防抖”和“节流”?其实并没有那么难,下边我先用一个大家日常游戏 Timi 王者荣耀中的两个情况“回城”和“施法”,其中防抖就是回城,而节流就是施法。
大家可能没Get到我们先学习一下,回过头大家就轻松拿捏了!
防抖
防抖 ,即确保某个函数在一段时间内之执行一次,但执行函数之后等待规定的时间内没有触发才会执行当前函数。
手搓一个防抖函数:
function debounce(fn,delay){
let timer;
return function(){
const _this = this;
const args = arguments;
if(timer){
clearTimeout(timer);
}
timer = setTimeout(()=>{
fn.apply(context, args);
},delay)
}
}
- 先创建一个定时器变量
timer; - 每次时间触发先判断是否存在定时器,若有则清楚之前的定时器;
- 若没有定时器,则新建定时器并存入到定时器变量中;
- 定时器时间到,执行回到运行
fn函数;
手搓一个防抖函数,可通过immediate判断是否立即执行:
// immediate为true时为立即执行,false为非立即执行
function debounce(func, wait, immediate) {
let timer;
return function () {
const _this = this;
const args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
const callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(_this, args)
}
else {
timer = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
}
| 特性 | 非立即执行 | 立即执行 |
|---|---|---|
| 首次触发 | 不立即执行,等 delay 后执行 | 立即执行 |
| 适用场景 | 用户输入完成后执行(如搜索框、表单验证) | 用户点击、首次操作时需要立即响应(如按钮点击) |
| 资源消耗 | 减少高频操作的资源消耗 | 适合需要立即响应的操作,如按钮防抖、API 请求 |
| 用户体验 | 更适合不需要立刻反应的场景 | 用户点击时,立即给予反馈,更直观的响应 |
使用场景:
- 电梯开门:电梯门在有人进出时会不断触发关闭倒计时,但只有在最后一次有人进入后的一段时间内无人再进出,电梯门才会真正关闭;
- 输入搜索:在搜索框输入内容时,用户每次输入都会触发搜索请求,但搜索请求应该在用户停止输入一段时间后再执行,避免频繁请求服务器。
节流
节流 ,即某个函数在短时间内多次触发,会按照固定的时间间隔执行,而不会让他高频触发。
手搓一个节流函数:
// 定时器版本
function throttle(func,wait){
let timer;
return function (){
const _this = this;
const args = arguments;
if(!timer){
timer = setTimeopunt(()=>{
fn.apply(_this, args);
timer = null;
},wait)
}
}
}
// 时间戳版本
function throttleWithTimestamp(fn, delay) {
let lastTime = 0;
return function () {
const _this = this;
const args = arguments;
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(_this, args); // 立即执行
lastTime = now;
}
};
}
- 先创建一个定时器变量
timer; - 事件触发都要判断是否存在定时器,若存在则不开启新的定时器;
- 若没有新的定时器,则开始定时器并存至
timer变量中; - 时间到,执行定时器回调,即执行
func函数并清空timer;
| 版本 | 触发时机 | 适用场景 |
|---|---|---|
| 时间戳版 | 立即执行,之后 delay 时间内不执行 | 鼠标移动、滚动事件(想要第一下生效) |
| 定时器版 | 不立即执行,delay 后执行 | 防止高频触发但不丢失最后一次执行 |
使用场景
- 公交车发车:即使乘客不断到达,公交车也会按照固定的时间间隔发车,而不会每到一个人就立刻发车;
- MOBA 游戏技能:即技能冷却之时不能进行技能的施放,当技能冷却转好之后才可以进行技能的释放。
总结
防抖和节流是相关的,它们都能提高网页的性能。只是它们应用于不同的情况:
- 防抖(Debounce)只关心最终状态:当事件频繁触发时,只有最后一次触发后
delay毫秒才执行,适用于需要最终结果的场景(如搜索框输入、表单验证)。 - 节流(Throttle)关心中间状态:以固定速率执行事件处理,适用于需要频繁处理但限制执行频率的场景(如滚动监听、窗口调整)。
上述时小弟的一点点理解,希望能一次积累进步,若存在错误请指出,谢谢大家!!!
学习参考:
1.防抖和节流及多种实现方式
2.一杯茶的时间🍵,带你彻底学会手写防抖节流
文章荐读: