以下是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后全部执行
因为清除的是上一次调用
set
时生成的延时器。clearTimeout
并不介意接收一个已经执行过的延时器,所以clearTimeout(timeout)
的实际效果等价于:那你可能会说,“下一次”执行
set
的时候岂不是就把“这一次”设置的timeout
给清除掉了?这就要看“下一次”是什么时候执行的:
如果这个时候
timeout
还没有过期,那么确实就应该把它给清除掉,这就是“防抖”的含义——时间小于某个阈值的连续操作,需要取消前面一次操作;timeout
已经过期了,那么清除不影响已经执行过的“上一次”的代码。