首先我们说一下应用场景,试想你在做一个根据input的值匹配搜索结果的功能,或者点击某个按钮请求接口进行关闭开启的功能。如果快速的输入或者点击是不是会对服务器造成压力或者造成接口的访问失败(在访问时间比较长的情况下)。
函数防抖就是为了解决这个问题的。那么我们说一下函数防抖的定义:函数防抖就是让某个操作对应的回掉函数在持续一段时间没有进行操作才执行。比如生活中的那种感应门一样,如果一直有人进来,或者间隔时间较短就不会关闭,只有一段时间以后没有人进来了才自动关闭了。那么放到js中应该怎么写呐?首先我们肯定需要一个函数,这个函数的参数有两个。第一个需要延时执行的函数,第二个延长的时间。我们先把架子搭起来。
function _debounce(func, time) {
}
那么,我们想我们该如何让一个函数延时执行呐?没错,就是setTimeout(),那么我们可以扔到里边去
function _debounce(func,time) {
function later() {
func()
}
return function () {
setTimeout(later, time)
}
}
好了,初步完成,但是这个东西只是执行了延迟执行,当我们不断进行操作,我们如何忽略这个操作呐?我们可以通过最后一次的操作和当前的时间进行判断,如果当前时间-最后一次操作的差大于等于我们设置的time就可以执行了。否则就不执行。
那么,我们要存储当前时间和最后一次执行
function _debounce(func,time) { let current function later() { if (new Date() - current>= time) { func() } } return function () { current = new Date() setTimeout(later, time) } }
好了,基本功能完成了,但是还有一个问题。我们的自定义操作函数是需要参数的,而且里边也会有this的绑定值的。那么我们怎么来处理呐。apply,与arguments或者剩余参数..arg
function _debounce(func,time) { let current,args,context,timeout; function later() { if (new Date() - current>= time) { func.apply(context,arags); timeout = null; } else {
timeout = setTimeout(func, time - (new Date()-current));
} } return function (...arg) { args = arg context = this current = new Date() if (!timeout) { timeout = setTimeout(later, time) } } }
欢迎大家评论,互相交流。
好了,功能我们实现了,接下来我们可以再稍微优化一下。试想我们会形成无数个timeout函数,并且最后都没有清楚。