前言
造点小轮子, 提高开发效率, 截流与防抖可用于性能优化, 防止用户暴力交互
throttle
截流: 一定时间内, 任务不管被调用多少次, 只实际执行一次
export function throttle (duration: number = 0): Function {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
const rawFunction: Function = descriptor.value
const getNewFunction: Function = (): Function => {
let start: number = Date.now()
const newFunction: Function = (...args) => {
const now: number = Date.now()
if (now - start >= duration) {
start = now
rawFunction.call(this, args)
}
}
return newFunction
}
descriptor.value = getNewFunction()
return descriptor
}
}
debounce
防抖: 任务被调用后, 在一定延迟后才执行, 若再次被调用, 则重新计算延迟时间
缺点: 若用户一直暴力调用, 则一直不执行
export function debounce (delay: number): Function {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
const rawFunction: Function = descriptor.value
const getNewFunction: Function = (): Function => {
let timer
const newFunction: Function = (...args) => {
if (timer) {
window.clearTimeout(timer)
}
timer = setTimeout(() => {
rawFunction.call(this, args)
}, delay)
}
return newFunction
}
descriptor.value = getNewFunction()
return descriptor
}
}
throttleDebounce
用截流优化后的防抖: 若暴力调用, 一定时间内至少实际执行一次
function throttleDebounce (delay: number): Function {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
const rawFunction: Function = descriptor.value
const getNewFunction: Function = (): Function => {
let timer
let start: number = Date.now()
const newFunction: Function = (...args) => {
const now: number = Date.now()
if (now - start >= delay) {
start = now
rawFunction.call(this, args)
} else {
if (timer) {
window.clearTimeout(timer)
}
timer = setTimeout(() => {
rawFunction.call(this, args)
}, delay)
}
}
return newFunction
}
descriptor.value = getNewFunction()
return descriptor
}
}
demo
用法
class Test {
@throttle(1000)
throttleTest () {
console.warn('throttleTest')
}
@debounce(1000)
debounceTest () {
console.warn('debounceTest')
}
@throttleDebounce(1000)
throttleDebounce () {
console.warn('throttleDebounce')
}
}