节流
事件触发n秒后执行回调,在这n秒期间多次触发该回调不会执行回调函数,在n秒时执行,之后再触发。
简易版
function throttle(fn, delay) {
if (typeof fn !== "function") throw new Error("第一个参数必须为函数!")
let timer
return function (...args) {
if (timer) return
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay)
}
}
复杂版
funciton now() {
return +new Date()
}
/**
* underscore 节流函数,返回函数连续调用时,func 执行频率限定为 次 / wait
*
* @param {function} func 回调函数
* @param {number} wait 表示时间窗口的间隔
* @param {object} options 如果想忽略开始函数的的调用,传入{leading: false}。
* 如果想忽略结尾函数的调用,传入{trailing: false}
* 两者不能共存,否则函数不能执行
* @return {function} 返回客户调用函数
*/
function throttle(fn, delay, options) {
// 判断fn是否为函数
if (typeof fn !== "function") throw new Error("第一个参数必须为函数")
let context, args, result
let timer = null
let previous = 0
if (!options) options = {}
const later = () => {
previous = options.leading === false ? 0, now()
timer = null
result = fn.apply(context, args)
if (!timer) context = args = null
}
return function() {
let nowDate = now()
if (!previous && options.leading === false) previous = nowDate
let remaining = delay - (nowDate - previous)
context = this
args = arguments
if (remaining <= 0 || remaining > delay) {
if (timer) {
clearTimeout(timer)
timer = null
}
previous = nowDate
result = fn.apply(context, args)
if (!timer) context = args = null
} else if (!timer && options.trailing !== false) {
timer = setTimeout(later, remaining)
}
return result
}
}