最近在看vue的 lazyload插件,里面用到了节流函数。对这一块不太了解,所以开始学习节流函数loadsh的源码,做一个记录吧,多做总结总是好的。
loadsh节流函数的API是这样的: _.throttle(func, wait, options);
节流函数的作用,其实就是和名字一样,限制某些功能函数的调用次数,或者起到延迟调用的效果。比如onmousemove、onkeyup、onresize等事件的监听函数,调用过于频繁时,可能会导致浏览器崩溃,节流函数可以有效的防止太过频繁的调用。
/*
* @param Function func 要进行节流的函数
* @param Number wait 想要的时间间隔
* @param Object options
* options.leading === true时,当第一次调用返回值函数时,立刻调用func;值是false时,执行返回值方法时会记录当前时间,当第二次调用时的时间间隔超过了wait,才调用func。
* options.trailing === true, 当执行返回值方法时,如果未达到wait的时间间隔,则启动延时调用func函数。值是false时,则不作处理,需要超过wait时间以后调用才有效。
*/
var throttle =
function(
func,
wait,
options) {
//默认leading和trailing的值都是true
const
_options = {
leading:
true,
trailing:
true
}
if (
Object.
prototype.
toString.
call(
options) ===
'[object Object]') {
Object.
assign(
_options,
options);
}
let
result =
null;
let
timer =
null;
let
previous =
0;
return
function() {
const
now = +
new
Date();
//第一次调用返回值方法时,且leading是false
if(
previous ===
0 &&
_options.
leading ===
false) {
previous =
now;
}
//计算是否超过了wait时间间隔
const
remain =
wait - (
now -
previous);
//如果超过了wait或者now小于previous,也就是手动修改时间的话,就立即执行func
if (
remain <=
0 ||
remain >
wait) {
//防止timer对即时调用func产生影响
if(
timer) {
clearTimeout(
timer);
timer =
null;
}
result =
func.
apply(
this,
arguments);
previous = +
new
Date();
}
//如果未超过wait,但是trailing是true的话,则开启延迟调用
else
if (
remain >
0 &&
_options.
trailing) {
console.
log(
'remain',
remain);
timer =
setTimeout(()
=> {
result =
func.
apply(
this,
arguments);
},
remain);
previous = +
new
Date();
}
}
return
result;
}