防抖和节流这两个在自己学习时可能不会接触到,或者说接触到但没有去注意。因为在日常的学习中基本不会用到这两个。而当你投入到工作时,这两个就必须得知道了。
为什么会用到防抖和节流?
当你在工作时写了很多行代码,这时浏览器在运行代码时可能会吃不消,此时就需要防抖和节流来优化浏览器的性能,使得浏览器能够流畅的运行代码。
什么是防抖和节流?
防抖和节流的作用都是防止函数多次调用。区别在于,假设一个用户一直触发这个函数,且每次触发函数的间隔小于设置的时间,防抖的情况下只会调用一次,而节流的情况会每隔一定时间调用一次函数。
防抖
防抖:限制事件被频繁触发。触发事件时,在一定时间内,若没有再次触发事件,则事件处理函数在时间到达时执行一次;若在一定时间内,又触发事件,则清除上一次的计时,重新开始计时,直到时间到了再执行函数。
通俗来说就是 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
代码实现防抖
// fn:表示需要防抖的函数,wait表示间隔的时间,immediate表示是否立即执行
let debounce = function (fn, wait, immediate){
let timer;// 声明定时器
return function () {
// 该函数是用户每次实际调用的防抖函数
let self = this;// 定义上下文对象
let args = arguments;// 获取函数参数,保证上下文对象不变,且仍然可以使用e参数
// 如果定时器已经存在,就清空定时器,重新定义一个新的定时器,重新计算时间,延迟执行用户传入的方法
if (timer) clearTimeout(timer);
if (immediate) {
let calNow = !timer;
timer = setTimeout(function () {
timer = null;
}, wait)
if (callNow) fn.apply(self, args);// 如果是立即执行的话,那么直接调用函数即可
} else {
timer = setTimeout (function () {
// 执行fn函数
fn.apply(self, args);// 函数的参数
}, wait)// 如果用户触发事件的时间间隔小于wait,那么在函数还没有执行的时候,就已经清空了定时器,开始了重新记录时间,函数行为并不会被执行;
}
}
}
节流
节流:限制事件被频繁触发。规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
也就是不管怎么触发,在一定时间内,只执行一次。
代码实现
function throttle(func, wait) {
let previous = 0;
let context, args, time, remaining;
return function() {
let now = +new Date();
context = this;
args = arguments;
remaining = wait - (now - previous)// 剩余的还需要等待的时间
if (remaining <= 0) {
func.apply(context, args);
previous = now // 重置“上一次执行”的时间
} else {
if (time) {
clearTimeout(time);
}
time = setTimeout(() => {
func.apply(context, args);
time = null;
previous = +new Date() // 重置“上一次执行”的时间
}, remaining) //等待还需等待的时间
}
};
}