Throttle:_.throttle(function, wait, [options])
创建并返回一个像节流阀一样的函数,当重复调用函数的时候,至少每隔 wait毫秒调用一次该函数。对于想控制一些触发频率较高的事件有帮助。
默认情况下,throttle将在你调用的第一时间尽快执行这个function,并且,如果你在wait周期内调用任意次数的函数,都将尽快的被覆盖。如果你想禁用第一次首先执行的话,传递{leading: false},还有如果你想禁用最后一次执行的话,传递{trailing: false}。
var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);
var now = Date.now;
// options 配置选项
// function 怎么去执行这个处理函数?
// 1:立即执行, 禁用最后一次执行, trailing: false
// 2:间隔wait毫秒之后执行, 阻止立即执行, +等待wait毫秒之后再去执行处理函数, leading: false
function throttle(func, wait, options) {
var lastTime = 0;
var args;
var timeoutId = null;
if (!options) {
options = {};
}
var later = function() {
// 更新lastTime 为 now
lastTime = options.leading ? 0 : now();
// 清空上次timeout
timeoutId = null;
func.apply(null, args);
};
return function() {
var nowTime = now();
args = arguments;
// leading: false,等待wait毫秒后执行
if (!lastTime && options.leading === false) {
lastTime = nowTime;
}
var remaining = wait - (nowTime - lastTime);
console.log(remaining);
if (remaining <= 0) {
if(timeoutId) {
// 清空上次timeout
clearTimeout(timeoutId);
timeoutId = null;
}
lastTime = nowTime;
func.apply(null, args);
}
else if (!timeoutId && options.trailing !== false) {
timeoutId = setTimeout(later, remaining);
}
};
}
debounce_.debounce(function, wait, [immediate])
返回 function 函数的防反跳版本, 将延迟函数的执行(真正的执行)在函数最后一次调用时刻的 wait 毫秒之后. 对于必须在一些输入(多是一些用户操作)停止到达之后执行的行为有帮助。 例如: 渲染一个Markdown格式的评论预览, 当窗口停止改变大小之后重新计算布局, 等等。
在 wait 间隔结束时,将使用最近传递给 debounced(去抖动)函数的参数调用该函数。
传参 immediate 为 true, debounce会在 wait 时间间隔的开始调用这个函数 。(注:并且在 waite 的时间之内,不会再次调用。)在类似不小心点了提交按钮两下而提交了两次的情况下很有用。 (感谢 @ProgramKid 的翻译建议)
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);
var now = Date.now;
var debounce = function(func, wait, immediate){
var lastTime;
var args;
var timeoutID;
var result;
var later = function(){
var last = now() - lastTime;
console.log(last);
if(last < wait) {
timeoutID = setTimeout(later, wait - last);
}
else {
timeoutID = null;
if(!immediate) {
result = func.apply(null, args);
}
}
};
return function() {
args = arguments;
lastTime = now();
//立即执行触发必须满足两个条件 immediate === true timeoutID === undefined
var callNow = immediate && !timeoutID;
if(!timeoutID) {
timeoutID = setTimeout(later, wait);
}
if(callNow) {
result = func.apply(null, args);
args = null;
}
return result;
};
};