函数去抖动和节流
我们常常会给一些经常触发的事件,比如resize、keyup绑定一些事件,当我们绑定过多或回调函数过于复杂时,往往会影响执行效率。 针对这种情况,我们可以使用去抖动或节流处理。
一、函数去抖动
去抖动,就是限制下次函数调用之前必须等待的时间间隔,换种理解方式的话,就是当调用函数n毫秒后,才会执行该函数,若在这n毫秒内又调用此函数则将重新计算执行时间。
/**
* 函数去抖动
* @param {Function} fn 连续被触发的函数
* @param {Object} context 触发上下文环境
*/
function debounce(fn, context){
clearTimeout(fn.timer);
fn.timer = setTimeout(function(){
fn.apply(context);
}, 500);
}
// 其他函数
var clickfn = function() {
console.log(new Date().getTime());
}
document.onclick = function() {
debounce(clickfn, window);
};
直接看代码,我们默认该函数只能在500ms中调用一次时,才会真正的执行。
原理很简单,设置一个需要延时的计时器,当在规定时间内再次调用时,重置定时器。当然至于延时,我们可以给个参数去设置。
注:fn别是匿名函数,否则会没有去抖动的效果。
考虑到触发时不能传入参数,再次做修改:
function debounce(fn, delay = 0){
let timer = null;
return function() {
var args = [].slice.call(arguments, 0)
var context = this
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
}
}
二、函数节流
节流函数只允许一个函数在规定的时间内只执行一次。
它和防抖动最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。
/**
* 函数节流
* @param {Function} fn 规定多少秒内必须执行的函数
* @param {Number} delay 规定的时间
*/
function throttle(fn, delay){
var timer = null;
return function(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
fn.apply(context,args);
timer = null;
},delay);
}
}
}
// 其他函数
var clickfn = function() {
console.log(new Date().getTime());
}
var callback = throttle(clickfn, 500);
document.onclick = function() {
callback();
};
利用闭包的性质,当点击时变绑定对应的延时处理函数,且在未执行完成的情况下不再去帮定,实现了节流方式。
注:注意闭包的使用。