在某些业务场景会频繁触发事件,如果不想频繁触发 这时候就需要用到函数节流和函数防抖了。
如果频繁用到 且还有去重 深浅拷贝 柯里化 推荐Lodash(https://www.lodashjs.com/)
//防抖函数(函数名,时间,是否立即实行)
function debounce(func, wait, immediate) {
let timeout, result;
let debounced = function () {
//改变this指向
let _this = this;
//改变event指向
let args = arguments;
clearTimeout(timeout);
if (immediate) {
//立即执行
let callnow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait);
if (callnow) {
result = func.apply(_this, args);
}
} else {
//延迟执行
timeout = setTimeout(function () {
func.apply(_this, args);
}, wait);
}
return result;
}
//取消操作
debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
}
return debounced;
}
//节流 频繁执行函数 leading 开始是否触发
//第一次会输出,最后一次不会被调用 leading:true,trailing:false
//第一次不会输出,最后一次会被调用 leading:false,trailing:true
//第一次会输出,最后一次会调用 leading:true,trailing:true
// trailing 结束是否触发
// throttle
function throttle(func, wait, options) {
let _this, args, timeout;
let old = 0; //时间戳
if (!options) {
options = {};
}
let later = function () {
old = new Date().valueOf();
timeout = null;
func.apply(_this, args)
}
return function () {
_this = this;
args = arguments;
let now = new Date().valueOf();
if (options.leading === false && !old) {
old = now;
}
if (now - old > wait) {
//第一次会执行
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
//立即执行
func.apply(_this, args)
old = now;
} else if (!timeout && options.trailing !== false) {
//最后一次会执行
timeout = setTimeout(later, wait);
}
}
}