vue3官网防抖ref?
以下是vue3官网的代码 “防抖ref”
import { customRef } from 'vue'
export function useDebouncedRef(value, delay = 200) {
let timeout
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newValue) {
clearTimeout(timeout)
timeout = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}
})
}
为什么set的时候,定时器已经清除了,定时器里的内容还会执行呢?newValue的值还会一直在,并且累积到200ms后全部执行
回复
1个回答
test
2024-07-09
因为清除的是上一次调用set
时生成的延时器。clearTimeout
并不介意接收一个已经执行过的延时器,所以clearTimeout(timeout)
的实际效果等价于:
if(xxxxx){
// 如果 timeout 对应的延时器有效,就清除该延时器
clearTimeout(timeout)
} else {
// 如果该延时器无效,就不用管
}
// 以上,timeout 指的是“上一次”的延时器
// 后面可以重新给 timeout 赋值,此后 timeout 就成了“这一次”的延时器
// 上面清除的是“上一次”的延时器,不会影响“这一次”的回调函数
那你可能会说,“下一次”执行set
的时候岂不是就把“这一次”设置的timeout
给清除掉了?这就要看“下一次”是什么时候执行的:
如果这个时候
timeout
还没有过期,那么确实就应该把它给清除掉,这就是“防抖”的含义——时间小于某个阈值的连续操作,需要取消前面一次操作;注意这里不存在“积累到
200ms
之后全部执行”的说法,而是上一次的newValue
在清除的时候就直接取消了,面试的时候可不能那样理解。- 如果这个时候
timeout
已经过期了,那么清除不影响已经执行过的“上一次”的代码。
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容