函数防抖(debounce)
创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait
毫秒后调用 func
方法。 debounced(防抖动)函数提供一个 cancel
方法取消延迟的函数调用以及 flush
方法立即调用。 可以提供一个 options(选项) 对象决定如何调用 func
方法,options.leading
与|或 options.trailing
决定延迟前后如何触发(是 先调用后等待 还是 先等待后调用)。 func
调用时会传入最后一次提供给 debounced(防抖动)函数 的参数。 后续调用的 debounced(防抖动)函数返回是最后一次 func
调用的结果。
注意: 如果 leading
和 trailing
选项为 true
, 则 func
允许 trailing 方式调用的条件为: 在 wait
期间多次调用防抖方法。
如果 wait
为 0
并且 leading
为 false
, func
调用将被推迟到下一个点,类似setTimeout
为0
的超时。
应用场景:实时搜索(keyup)、拖拽(mousemove)
_.debounce(func, [wait=0], [options={}])
lodash在opitons参数中定义了一些选项,主要是以下三个:
leading,函数在每个等待时延的开始被调用,默认值为false
trailing,函数在每个等待时延的结束被调用,默认值是true
maxwait,最大的等待时间,因为如果debounce的函数调用时间不满足条件,可能永远都无法触发,因此增加了这个配置,保证大于一段时间后一定能执行一次函数
根据leading和trailing的组合,可以实现不同的调用效果:
leading-false,trailing-true:默认情况,即在延时结束后才会调用函数
leading-true,trailing-true:在延时开始时就调用,延时结束后也会调用
leading-true, trailing-false:只在延时开始时调用
deboucne还有cancel方法,用于取消防抖动调用
事例:
// 避免窗口在变动时出现昂贵的计算开销。
jQuery(window).on('resize', _.debounce(calculateLayout, 150));
// 当点击时 `sendMail` 随后就被调用。
jQuery(element).on('click', _.debounce(sendMail, 300, {
'leading': true,
'trailing': false
}));
// 确保 `batchLog` 调用1次之后,1秒内会被触发。
var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
var source = new EventSource('/stream');
jQuery(source).on('message', debounced);
// 取消一个 trailing 的防抖动调用
jQuery(window).on('popstate', debounced.cancel);
场景使用
function test() {
console.log(11)
}
function debounce(method, context) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(context)
}, 500)
}
window.onresize = function() {
debounce(test, window);
}
函数节流(throttle)
创建一个节流函数,在 wait 秒内最多执行 func
一次的函数。 该函数提供一个 cancel
方法取消延迟的函数调用以及 flush
方法立即调用。 可以提供一个 options 对象决定如何调用 func
方法, options.leading 与|或 options.trailing 决定 wait 前后如何触发。 func
会传入最后一次传入的参数给这个函数。 随后调用的函数返回是最后一次 func
调用的结果。
注意: 如果 leading
和 trailing
都设定为 true
则 func
允许 trailing 方式调用的条件为: 在 wait
期间多次调用。
如果 wait
为 0
并且 leading
为 false
, func
调用将被推迟到下一个点,类似setTimeout
为0
的超时。
应用场景:窗口调整(resize)、页面滚动(scroll)、抢购疯狂点击(mousedowm)
throttle将一个函数的调用频率限制在一定阈值内,例如1s内一个函数不能被调用两次。
_.throttle(func, [wait=0], [options={}])
实例:
// 避免在滚动时过分的更新定位
jQuery(window).on('scroll', _.throttle(updatePosition, 100));
// 点击后就调用 `renewToken`,但5分钟内超过1次。
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);
// 取消一个 trailing 的节流调用。
jQuery(window).on('popstate', throttled.cancel);
_.throttle和_.debounce的区别:
虽然在等待时间内函数都不会再执行,但_.throttle在第一次触发后开始计算等待时间,
_.debounce在最后一次触发之后才计算等待时间(最后一次在等待时间范围内)
参考资料: https://www.lodashjs.com/docs/latest#_debouncefunc-wait0-options
https://www.lodashjs.com/docs/latest#_throttlefunc-wait0-options