函数防抖
最近的练手项目web-terminal中(也就是一个网页终端,可执行一些命令),在按下键盘后会显示可能匹配的命令列表(假设对应的函数是setHintList
),这不仅是按下字母按键会触发,按下删除键、tab键都会触发。那就不得不考虑一个问题,如果我们手速太快,那么setHintList
就会频繁触发,但我们只需要响应用户最后一次输入的命令即可,虽然在这个小项目中没啥问题,但是由此可以引出一些对于以后大项目的考虑:如何减小这种多次频繁执行函数带来的性能开销问题?那就是函数防抖~
函数防抖是一种优化技术,用来限制某个函数在一定时间内被调用的频率。当事件被触发后,它会等待一段时间,如果在这段时间内再次被触发,那么它会重新开始等待。
下面是一种实现方式:
1 | export function buildDebounce(fn: (...arg: any[]) => any, duration: number = 300) { |
buildDebounce
接受一个函数fn
和一个可选的时间间隔duration
(默认为 300 毫秒)作为参数,并返回一个新的函数。
- 内部使用了一个变量
timer
来跟踪定时器的引用。初始值为 -1,表示没有定时器在运行。 - 返回的函数在被调用时,首先检查
timer
是否大于 -1。如果是,说明之前已经有一个定时器在运行,此时会调用clearTimeout
清除这个定时器,以取消之前可能正在等待执行的函数调用。 - 然后,使用
window.setTimeout
创建一个新的定时器,在duration
毫秒后执行传入的函数fn
,并通过bind
方法确保函数在正确的上下文中执行。 - 当定时器执行完函数后,将
timer
重置为 -1,表示没有定时器在运行。
在(this: unknown, ...args: any[])
中,this
的值是在调用由buildDebounce
返回的函数时,根据调用的上下文确定的。也就是当这个返回的函数被调用时,通过保留传入的 this
值,可以确保在最终执行被包裹的函数 fn
时,fn
能够在正确的上下文中执行。
buildDebounce
的使用如下:
1 | function printMessage(message) { |