应用场景
两个函数都是为了优化高频率事件,如用户input事件、window.resize、window.scroll,具体哪些场景用哪个,要理解两个函数,然后根据需求来看
防抖(debounce)
防抖(debounce)在处理多频率事件时,可以理解成:
在限定时间内再次触发,会重新计时
比如我们时间设置为5秒后执行事件,在这5秒内有很多次事件发生,每次的事件都会清掉之前的计时,只从最后一次事件触发往后计时5秒
// 编写思路:需要接收一个函数参数,返回包装后的函数,业务函数(参数函数)的执行频次被控制了
function debounce(fn, delay) {
var timer; // 每次事件执行会共用一个计时器变量
return function (...args) { // 接收一个函数,返回一个包装函数,事件触发时实际执行的是此函数
clearTimeout(timer); // 在delay时间内再次触发事件,会清掉之前的计时器,重新计时
timer = setTimeout(() => {
fn.apply(this, args) // 传递this, 传递执行函数的参数
}, delay); //delay后执行
}
};
// 业务主体函数
function reqSearch(v){
console.log('ready to request:', v)
}
// debounce包装后的函数
var dReqSearch = debounce(reqSearch, 1000);
var input = document.querySelector('input');
input.addEventListener('input', function(e){
dReqSearch(e.target.value)
})
节流(throttle)
节流(throttle)节省不必要的流量;在处理多频率事件时,可以理解成: 在限定一段时间内触发的多次事件,我们只处理一次,其他的视为无效事件
也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活(类似于技能冷却时间)
function throttle(fn, delay) {
var valid = true; //是否处理事件的开关
return function(...args){
if(valid) { // 有效事件进来后,settimeout开始计时,不处理后续事件,直到限定时间过去后
valid = false;
fn.apply(this, args) // 传递this, 传递执行函数的参数
setTimeout(() => {
valid = true
}, delay);
}
}
}
lodash的防抖和节流
lodash的函数里多了两个配置项leading和trailing,可以决定在延迟开始前和后执行函数
debounce API
_.debounce(func, [wait=0], [options={}])
func (Function): 要防抖动的函数。
[wait=0] (number): 需要延迟的毫秒数。
[options={}] (Object): 选项对象。
[options.leading=false] (boolean): 指定在延迟开始前调用,默认false。
[options.maxWait] (number): 设置 func 允许被延迟的最大值。
[options.trailing=true] (boolean): 指定在延迟结束后调用,默认true
throttle API
_.throttle(func, [wait=0], [options={}])
func (Function): 要节流的函数。
[wait=0] (number): 需要节流的毫秒数。
[options={}] (Object): 选项对象。
[options.leading=true] (boolean): 指定调用在节流开始前,默认true。
[options.trailing=true] (boolean): 指定调用在节流结束后,默认true。