小议函数的节流和防抖
why
在前端开发中有一部分用户行为会频繁的触发事件执行,而对于DOM的操作、资源加载等耗费性能的处理,很可能会导致界面卡顿,甚至浏览器奔溃。函数的节流与防抖就是为了解决类似需求而产生的。
概念及应用
- 节流:函数的节流就是预定一个函数只有在大于等于执行周期时才会执行,周期内调用不会执行。
主要应用场景有:scroll、touchmove - 防抖:抖动停止后的时间超过设定的时间时执行一次函数。注意:这里的抖动停止表示你停止了触发这个函数,从这个时间点开始计算,当间隔时间等于你设定时间,才会执行里面的回调函数。如果你一直在触发这个函数并且两次触发间隔小于设定时间,则一定不会到回调函数那一步。
主要应用场景有:input验证、搜索联想、resize
实现思路
节流实现思路就是定一个时间间隔,在这个时间间隔范围内,只会执行一次函数。
防抖实现思路是首次运行时把定时器赋值给一个变量,第二次执行时,如果间隔没超过定时器设定的时间则会清除掉定时器,重新设定定时器,依次反复,当我们停止下来时,没有执行清除定时器,超过一定时间后触发回调函数
code
- 节流函数
// 1. 思考不用定时器可以实现么,让我们试试
function throttle(fn, delay = 1000) {
var time = Date.now();
return function() {
if(Date.now()-time > delay) {
fn();
time = Date.now();
} else {
return;
}
}
}
// 2. 有定时器为什么不用呢,哈哈哈
function throttle(fn, delay = 1000) {
var timer = null;
return function(){
if (timer) {return;}
else {
timer = setTimeout(()=>{
fn.call(this,arguments);
timer = null;
},delay);
}
}
}
// test
window.addEventListener('scroll', throttle(foo,1000));
function foo() {
console.log('hello')
}
- 防抖函数
// 1. 无定时器
// function debounce(fn, delay = 1000) {
// var time = Date.now();
// return function(){
// if(Date.now()-time > 1000) {
// fn();
// } else {
// time = Date.now();
// return;
// }
// }
// }
// 2. 有定时器
function debounce(fn, delay = 1000) {
var timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.call(this,arguments);
timer = null;
},delay);
}
}
// test
window.addEventListener('scroll', debounce(foo,1000));
function foo() {
console.log('hello')
}
参考
- JavaScript 高级程序设计 第22章 22.3.3函数节流 [美] Nicholas C.Zakas
- js函数节流与防抖如何实现
- JS节流和防抖的区分和实现详解
- JavaScript函数节流和函数防抖之间的区别
人生如逆旅,我亦是行人