防抖函数
大约 1 分钟
概述
- 当事件触发时,函数
fn
不会立即执行,而是等待一段时间 - 若等待时间内没有再次触发事件,则执行函数
fn
- 当事件被频繁触发时,防抖函数
debounce
表现为延迟执行
实现
type fnType<T> = (...args: T[]) => any
/**
* 防抖
* @param fn 需要防抖的函数
* @param delay 延迟时间, 单位毫秒 ms, 默认 200
* @param immediate 是否立即执行, 默认不立即执行
* @returns 防抖化的函数
*/
function debounce<T = any>(fn: fnType<T>, delay: number = 200, immediate: boolean = false) {
let timer: any = null
let isInvoke = false // 是否已执行
const _debounce = function(...args: T[]) {
return new Promise<T>((resolve, reject) => {
// 清除计时器
if (timer) clearTimeout(timer)
if (!isInvoke && immediate) { // 立即执行 1 次
try {
const result = fn.apply(this, args)
// 立即执行完成
isInvoke = true
resolve(result)
} catch(err: any) {
reject(err)
}
} else {
timer = setTimeout(() => {
try {
const result = fn.apply(this.args)
// 执行完成, 初始化所有变量
timer = null
isInvoke = false
resolve(result)
} catch (err: any) {
reject(err)
}
}, delay)
}
})
}
// 取消执行
_debounce.cancel = function() {
clearTimeout(timer)
timer = null
}
return _debounce
}
/**
* 防抖
* @param {Function} fn 需要防抖的函数
* @param {number} delay 延迟时间, 单位毫秒 ms, 默认 200
* @param {boolean} immediate 是否立即执行, 默认不立即执行
* @returns 防抖化的函数
*/
function debounce(fn, delay = 200, immediate = false) {
let timer = null
let isInvoke = false // 是否已执行
const _debounce = function(...args) {
return new Promise((resolve, reject) => {
// 清除计时器
if (timer) clearTimeout(timer)
if (!isInvoke && immediate) { // 立即执行 1 次
try {
const result = fn.apply(this, args)
// 立即执行完成
isInvoke = true
resolve(result)
} catch(err) {
reject(err)
}
} else {
timer = setTimeout(() => {
try {
const result = fn.apply(this, args)
// 执行完成, 初始化所有变量
timer = null
isInvoke = false
resolve(result)
} catch(err) {
reject(err)
}
}, delay)
}
})
}
// 取消执行
_debounce.cancel = function() {
clearTimeout(timer)
timer = null
}
return _debounce
}