JavaScript中函数节流的debounce模式

函数节流是什么

  在事件处理机制中可能会出现在极短的时间内多次执行事件处理函数,比如监听了键盘敲击事件,下面以一个具体需求来举例说明:当用户在文本框输入关键字时,自动查询匹配的关键字并将结果返回给用户。我们可以通过绑定文本框的键盘事件来监听输入框内容变化,一旦变化就向后台查询匹配关键字并返回以展示。假设我想查询“blackberry”,它包含10个字符,也许输入完成只花了1秒钟左右,那么在这1秒内就会调用10次查询方法。这是一件非常恐怖的事情,如果淘宝的搜索框也这样实现,那就不禁让人担心它会不会在光棍节到来的几分钟之内就挂掉了(当然,它也许并没有这么脆弱,但这绝对不是最好的方案)
  更好的方法是,我们希望用户已经输入完成,或者正在等待提示(也许他懒得再输入后面的内容)的时候,再查询匹配关键字。
  最后我们发现,在我们期望的这两种情况下,用户会暂时停止输入,于是我们决定在用户暂停输入200毫秒后再进行查询(如果用户在不断地输入内容,那么我们认为他可能很明确自己想要的关键字,所以等一等再提示他)
  这时,利用debounce函数,我们可以轻松实现这个需求。

函数节流示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Function.prototype.debounce = function (delay) {
var timestamp, timeout, result, context, caller = this, args
var later = function () {
var last = new Date() - timestamp
if (last < delay && last >= 0) {
timeout = setTimeout(later, delay - last)
} else {
timeout = null
result = caller.apply(context, args)
}
}
return function() {
args = arguments
context = this
timestamp = new Date()
if (!timeout) timeout = setTimeout(later, delay)
return result
}
}
//用法
var print = function(str) { console.log(str) }.debounce(2000)
document.body.addEventListener('click', function(e) {
print('clicked!')
})