防抖
使用isDebouncing
判断是否处于防抖窗口 deboTimer
是重置isDebouncing
计时器的id
- 非窗口期间调用函数 会设置窗口.如果
leading
为true,调用fn - 窗口期间调用函数 会重置窗口持续时间 并在窗口结束时以当前参数(也是最后一次参数)调用fn
js
export const debo = (fn, options = {}) => {
const {
leading = false, // 是否立即执行
trailing = true, // 是否执行最后一次
delay = 200,
} = options
let isDebouncing // 是否处于防抖窗口
let deboTimer // 重置isDebouncing的计时器id
function deboFn(...args) {
if (!isDebouncing) {
if (leading) {
fn.call(this, ...args)
}
// 不处于防抖窗口时 将isDebouncing设为true持续delay毫秒
isDebouncing = true
deboTimer = setTimeout(() => {
isDebouncing = false
}, delay)
} else {
// 处于防抖窗口时 重置窗口的持续时间
clearTimeout(deboTimer)
deboTimer = setTimeout(() => {
isDebouncing = false
if (trailing) {
// 在当前窗口结束后 以最后一次的参数调用fn
fn.call(this, ...args)
}
}, delay)
}
}
const cancel = () => {
clearTimeout(deboTimer)
isDebouncing = false
}
return {
deboFn,
cancel,
}
}
节流
使用isThrottling
判断是否处于防抖窗口 throTimer
是重置isThrottling
计时器的id lastArgs
是最后一次调用此函数的参数
- 非窗口期间调用函数,如果
leading
为true,调用fn(不会设置lastArgs
).设置窗口.在窗口结束时,以lastArgs
调用fn,将lastArgs
设置为null. - 窗口期间调用函数 不会重置窗口持续时间.保存当前参数至
lastArgs
js
export const thro = (fn, options = {}) => {
const {
leading = true, // 是否立即执行
trailing = false, // 是否执行最后一次
delay = 200,
} = options
let isThrottling // 是否处于节流窗口
let throTimer // 重置isThrottling的计时器id
let lastArgs
function throFn(...args) {
if (!isThrottling) {
if (leading) {
fn.call(this, ...args)
}
// 不处于节流窗口时 将isThrottling设为true持续delay毫秒
isThrottling = true
throTimer = setTimeout(() => {
isThrottling = false
if (trailing && lastArgs) {
// 在当前窗口结束后 以最后一次的参数调用fn
fn.call(this, ...lastArgs)
lastArgs = null
}
}, delay)
} else {
// 处于节流窗口时 不干涉其持续时间
// 记录当前args 供窗口结束时可能的调用
lastArgs = args
}
}
const cancel = () => {
clearTimeout(throTimer)
isThrottling = true
lastArgs = null
}
return {
throFn,
cancel,
}
}