在做JavaScript交互中,我们经常会需要监听一些容易频繁触发的事件。比如键盘、scroll事件、resize事件、input事件。如果每次事件触发都去执行对应的回调函数的话,会导致回调函数的频繁执行。假如我们在回调函数里做了异步请求,就会频繁的请求后台,导致了页面上很多异步请求的堆积,也加重了服务器端的压力。这种情况下,我们需要做一些处理,以避免回调函数过于频繁的执行。防抖可以有效的解决这个问题。
防抖 -- 防止回调函数的频繁执行。
/*
* func: 真正执行的函数
* wait: 规定的多久时间会调用func
* immediate: true,立即触发执行,在间隔小于wait都不再触发。false或者不传,不会立即触发,在间隔大于wait时会触发一次。
*/
function debounce(func, wait, immediate) {
// 作为闭包访问的变量,一直处在外层作用域中,保存setTimeout返回的id。
var timeout;
return function() {
var args = arguments;
var context = this;
var later = function() {
timeout = null;
if (!immediate) {
func.call(context, args);
}
};
var callNow = immediate && !timeout;
// 如果在指定的wait时间内清除timeout,以达到不执行func函数。
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.call(context, args);
}
};
}
节流函数最主要的不同在于,规定了在指定时间内至少会执行一次回调函数。比如在图片的懒加载中,我们不希望在滚动开始或者停止时执行一次加载,我们希望的是在滚动中不断的加载图片。
节流 -- 保证在 X 毫秒内至少执行一次回调函数
function throttle(func, wait, mastRun) {
var timeout,
startTime = Date.now();
return function() {
var args = arguments,
context = this;
curTime = Date.now();
clearTimeout(timeout);
// 如果达到了规定的触发时间
if (curTime - startTime >= mastRun) {
func.call(context, args);
startTime = Date.now();
} else {
timeout = setTimeout(func, wait);
}
}
}