function throttle (f, wait) {
let last = 0
return function (...args) {
const now = Date.now()
if (now - last > wait) {
f.call(this, ...args)
last = now
}
}
}
使用 setTimeout
function throttle (f, wait) {
let timer = null
return function (...args) {
if (timer === null) {
timer = setTimeout(() => {
f.call(this, ...args)
timer = null
}, wait)
}
}
}
防抖(debounce)
概念
当调用一个函数时,先等待一段时间再调用,如果在等待期间又调用了这个函数,则重置等待的时间,以控制函数调用频率。
应用
例如输入框搜索建议。当用户输入内容的时候,触发函数去请求后台给用户提供建议,如果用户一个单词都没输入完,每个字母都去发起请求,就很没必要。这时可加入防抖,例如防抖 300ms ,用户输入内容时,如果 300ms 内没有再输入,则发起一次请求。
实现
节流(throttle)
概念
对于一个函数的频繁调用,在一定时间内只调用一次。
应用
例如监听 scroll 事件实现懒加载,如果用户疯狂拖动滚动条却不拖到底下,绑定的处理函数就会疯狂被调用,这时候我们可以降低函数被调用的频率,不管用户怎么拖动,在一定时间(例如 300ms)内,都只会调用一次处理函数。
实现
使用
setTimeout
上述两种写法不同的是,
setTimeout
是在wait
时间的末尾才执行的第一次调用,且参数是第一次调用的参数;而第一种写法一开始就会调用一次。如果
setTimeout
写法要执行最新一次的调用,即参数是最新的而不是第一次的,那需要在每次调用的时候更新args
,否则f.call(this, ...args)
中的args
一直不会被更新:拓展
以上写法已经达到了限制函数调用频率的目的,如果需要跟 lodash 这类库函数一样完善,还需要加上几个配置来决定是要在
wait
的开头还是末尾调用,同时提供清除等待等方法,这边就不再赘述,可自行去查阅源码。