函數(shù)節(jié)流是什么?
在事件處理機制中可能會出現(xiàn)在極短的時間內(nèi)多次執(zhí)行事件處理函數(shù)刽酱,比如監(jiān)聽了鍵盤敲擊事件,下面以一個具體需求來舉例說明:當(dāng)用戶在文本框輸入關(guān)鍵字時断盛,自動查詢匹配的關(guān)鍵字并將結(jié)果返回給用戶罗洗。我們可以通過綁定文本框的鍵盤事件來監(jiān)聽輸入框內(nèi)容變化,一旦變化就向后臺查詢匹配關(guān)鍵字并返回以展示钢猛。假設(shè)我想查詢“blackberry”伙菜,它包含10個字符,也許輸入完成只花了1秒鐘左右命迈,那么在這1秒內(nèi)就會調(diào)用10次查詢方法贩绕。這是一件非常恐怖的事情壶愤,如果淘寶的搜索框也這樣實現(xiàn)淑倾,那就不禁讓人擔(dān)心它會不會在光棍節(jié)到來的幾分鐘之內(nèi)就掛掉了(當(dāng)然,它也許并沒有這么脆弱征椒,但這絕對不是最好的方案)
更好的方法是娇哆,我們希望用戶已經(jīng)輸入完成,或者正在等待提示(也許他懶得再輸入后面的內(nèi)容)的時候,再查詢匹配關(guān)鍵字碍讨。
最后我們發(fā)現(xiàn)治力,在我們期望的這兩種情況下,用戶會暫時停止輸入勃黍,于是我們決定在用戶暫停輸入200毫秒后再進行查詢(如果用戶在不斷地輸入內(nèi)容宵统,那么我們認為他可能很明確自己想要的關(guān)鍵字,所以等一等再提示他)
這時覆获,利用debounce函數(shù)马澈,我們可以輕松實現(xiàn)這個需求。
<pre>
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!') })
</pre>