节流(throttle)和去抖(debounce)
面试时经常会被问到,怎么去控制用户频繁的滚动,输入操作,我一般都会脱口而出,节流去抖呀,然后专业点的面试官总会接上一句:“你能自己实现一个吗?”
然后我就有点懵逼😓,实现起来好像也不简单啊。
不懂就来学,先找了下别人的实现,然后根据自己理解,手写了一遍,也算是弄清楚了,所以记录一下
Throttle
var throttle = function (fn, interval) {
// 记录前一次时间
var last = +new Date()
var timerId = null
// 包装完后返回 闭包函数
return function () {
var current = +new Date()
var args = [].slice.call(arguments, 0)
var context = this
// 首先清除定时器
clearTimeout(timerId)
// current 与last 间隔大于interval 执行一次fn
// 在一个周期内 last相对固定 current一直再增加
// 这里可以保证调用很密集的情况下 current和last 必须是相隔interval 才会调用fn
if (current - last >= interval) {
fn.apply(context, args)
last = current
} else {
// 如果没有大于间隔 添加定时器
// 这可以保证 即使后面没有再次触发 fn也会在规定的interval后被调用
timerId = setTimeout(function() {
fn.apply(context, args)
last = current
}, interval)
}
}
}
Debounce
var debounce = function (fn, interval) {
// debounce中的interval 和 throttle中的 interval含义不一样
// 在debounce中可以可以把interval理解成 用户停止了某个连续的操作后 再推迟interval执行fn
var timerId = null
return function () {
var current = +new Date()
var args = [].slice.call(arguments, 0)
var context = this
// 如果调用很密集 可以保证fn永远不会触发 必须等到有前后两个调用的间隔大于等于interval fn才能被执行
// 如果调用很少 fn会在interval结束后被执行
clearTimeout(timerId)
timerId = setTimeout(function() {
fn.apply(context, args)
}, interval)
}
}
网友评论