简单记录一下函数防抖和节流,代码来自B站小野森森老师
1、函数防抖
函数防抖主要用于解决多次触发回调函数时造成的资源浪费问题。通过控制两次触发的时间间隔,达到只有时间间隔大于等于设定值才执行回调函数的效果。主要思路是每次触发回调函数时,先清空上次设置的定时器,然后设置新的定时器,重新计时。当两次操作时间间隔大于设置的时间时,定时器会被触发,从而执行回调函数,否则定时器被清空。
/**
* fn 需要执行的回调函数
* time 时间间隔
* trigger 是否在首次触发回调函数时立即执行
*/
function debounce (fn, time, trigger) {
var t = null;
var debounced = function () {
var _self = this,
args = arguments;
// 清空定时器
clearTimeout(t);
if (trigger) {
// 首次触发立即执行,需要一个条件做判断,每次满足这个条件就执行回调函数
var executor = !t; // t 为 null 时,表示满足条件
t = setTimeout(function () {
// 每次设置定时器使的time后将 t 置为 null,这样当两次触发时间间隔大于等于time时,t的值为null,下一次触发就直接调用回调函数了
t = null;
}, time);
if (executor) {
fn.apply(_self, args);
}
} else {
// 首次触发时也延迟执行,这块也是函数防抖的主要逻辑,在下一次触发回调函数前,如果已经等于或者超过了time,则fn会被执行,否则在fn被执行前定时器就被清空了
t = setTimeout(function () {
fn.apply(_self, args);
}, time);
}
}
// 设置清空函数防抖的方法
debounced.remove = function () {
clearTimeout(t);
t = null;
}
return debounced;
}
2、函数节流
和函数防抖一样,函数节流也用于避免资源浪费等现象。不同的是,函数节流是规定在固定时间内回调函数一定会被执行且只执行一次。因此,重复触发事件,使用函数防抖可能会导致回调函数只执行一次,而函数节流可能会执行多次。
/**
* fn 回调函数
* delay 延迟时间
*/
function throttle (fn, delay) {
var t = null,
startTime = new Date().getTime();
var throttler = function () {
var _self = this,
args = arguments,
endTime = new Date().getTime();
// 清空定时器
clearTimeout(t);
if (endTime - startTime >= delay) {
fn.apply(_self, args);
startTime = endTime;
} else {
// 这里是保证最后一次触发事件时一定会触发一次回调函数
t = setTimeout(function () {
fn.apply(_self, args);
}, delay);
}
}
throttler.remove = function () {
clearTimeout(t);
t = null;
}
return throttler;
}
总结
函数防抖主要用于在固定时间间隔内阻止回调函数进行,而函数节流则要求回调函数在固定时间间隔内只执行一次。通常可以在发送ajax
请求时使用函数防抖,在轮播图
和输入框验证
时使用函数节流。