防抖(Debounce)
原理:当事件被触发后,延迟一段时间(比如 300ms)再执行目标函数。如果在这段时间内事件再次被触发,就重新计时,只有当事件停止触发一段时间后,函数才会真正执行。
场景:适合需要“等一等”的情况,比如搜索框输入,用户输入完后再发起请求。
形象记忆:想象你在等人挤电梯。每次有人来(事件触发),你就重新等几秒,确保没人再来时才关门(执行函数)。如果一直有人来,你就一直推迟关门。
节流(Throttle)
原理:在事件触发时,立即执行函数,但设置一个时间间隔(比如 300ms),在此间隔内即使事件再次触发,函数也不会再次执行,直到下个时间间隔到来。
场景:适合需要“控制频率”的情况,比如滚动监听、鼠标移动,确保函数不会过于频繁执行。
形象记忆:想象你在玩射击游戏,节流就像机关枪的射速限制——每秒只能射一次(固定间隔执行),不管你多快按扳机,子弹发射都有节奏。
防抖节流总结:
防抖函数一般用于表单搜索,点击事件等场景,目的就是为了防止短时间内多次触发事件。
节流函数一般为了降低函数执行的频率,比如滚动条滚动,鼠标跟踪。
debounce
假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯;
如果在电梯门关闭之前,又有人来了,你会继续开门;
这样一直进行下去,你可能需要等待几分钟,最终没人进电梯了,才会关闭电梯门,然后上楼。
debounce 函数会通过闭包维护一个 timer
当同一 action 在 delay 的时间间隔内再次触发,则清理 timer,然后重新设置 timer
const debounce = (fn, wait) => {
var timerId = null;
return function () {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn.apply(this, arguments);
}, wait);
};
};
所以 debounce 的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
throttle
假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯;
但是,你是个没耐心的人,你最多只会等待电梯停留一分钟;
在这一分钟内,你会开门让别人进来,但是过了一分钟之后,你就会关门,让电梯上楼。
const throttle = (fn, wait) => {
var wait = wait || 0;
var lastTime = 0;
return function () {
var currentTime = +new Date();
if (currentTime > lastTime + wait) {
lastTime = currentTime;
fn.apply(this, arguments);
}
};
};
function debounce(fn, wait) {
// 先说下是干啥的 防抖
var timerId = null;
// 电梯举例: 加入你坐电梯,你设置时间,在这个时间段内,只要有人按 你就会暂停。这个过程可能需要等待几分钟,最终没人进电梯了
return function () {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn.apply(this, arguments);
}, wait);
};
}
function throttle(fn, wait) {
// 节流代表的意思是 你是个很没有耐心的人 throttle
// 这个时间段内 执行多少次 你不管 ,只要超过了 这个时间 你就会走
var lastTime = 0;
return function () {
currentTime = +new Date();
if (currentTime > lastTime + wait) {
lastTime = currentTime;
fn.apply(this, arguments);
}
};
}
function debounce(fn, wait) {
let timerId = null;
return function () {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn.apply(this, arguments);
}, wait);
};
}
function throttle(fn, wait) {
var waite = wait || 0;
var lastTime = 0;
return function () {
var currentTime = +new Date();
if (currentTime > lastTime + waite) {
lastTime = currentTime;
fn.apply(this, arguments);
}
};
}
//去抖动
const debounce = (fn, wait) => {
var timerId = null;
return function () {
if (timerId) {
clearTimeout(timerId);
}
timerId = setTimeout(() => {
fn.apply(this, arguments);
}, wait);
};
};
// 节流
const throttle = (fn, wait) => {
var lastTime,
wait = wait || 0;
return function () {
var currentTime = +new Date();
if (currentTime - lastTime > wait) {
lastTime = currentTime;
fn.apply(this, arguments);
}
};
};