函數節流是指控制一個函數的執行頻率或間隔(就像控制水流的閘門同樣),Underscore提供了debounce()和throttle()兩個方法用於函數節流。javascript
爲了更清楚地描述這兩個方法,假設咱們須要實現兩個需求:java
需求1:當用戶在文本框輸入搜索條件時,自動查詢匹配的關鍵字並提示給用戶(就像在Tmall輸入搜索關鍵字時那樣)windows
首先分析第1個需求,咱們能夠綁定文本框的keypress事件,當輸入 框內容發生變化時,查詢匹配關鍵字並展現。假設我想查詢「windows phone」,它包含13個字符,而我輸入完成只花了1秒鐘(好像有點快,就意思意思吧),那麼在這1秒內,調用了13次查詢方法。這是一件很是恐怖的事 情,若是Tmall也這樣實現,我擔憂它會不會在光棍節到來以前就掛掉了(固然,它並無這麼脆弱,但這絕對不是最好的方案)瀏覽器
更好的方法是,咱們但願用戶已經輸入完成,或者正在等待提示(也許他懶得再輸入後面的內容)的時候,再查詢匹配關鍵字。服務器
最後咱們發現,在咱們指望的這兩種狀況下,用戶會暫時中止輸入,因而咱們決定在用戶暫停輸入200毫秒後再進行查詢(若是用戶在不斷地輸入內容,那麼咱們認爲他可能很明確本身想要的關鍵字,因此等一等再提示他)函數
這時,利用Underscore中的debounce()函數,咱們能夠輕鬆實現這個需求:spa
<input type="text" id="search" name="search" />
<script type="text/javascript">
var query = _(function() {
// 在這裏進行查詢操做
}).debounce(200);
$('#search').bind('keypress', query);
</script>接口
你能看到,咱們的代碼很是簡潔,節流控制在debounce()方法中已經被實現,咱們只告訴它當query函數在200毫秒內沒有被調用過的話,就執行咱們的查詢操做,而後再將query函數綁定到輸入框的keypress事件。事件
query函數是怎麼來的?咱們在調用debounce()方法時,會傳 遞一個執行查詢操做的函數和一個時間(毫秒數),debounce()方法會根據咱們傳遞的時間對函數進行節流控制,並返回一個新的函數(即query函 數),咱們能夠放心大膽地調用query函數,而debounce()方法會按要求幫咱們作好控制。ip
需求2:當用戶拖動瀏覽器滾動條時,調用服務器接口檢查是否有新的內容
再來分析第2個需求,咱們能夠將查詢方法綁定到window.onscroll事件,但這顯然不是一個好的作法,由於用戶拖動一次滾動條可能會觸發幾十次甚至上百次onscroll事件。
咱們是否可使用上面的debounce()方法來進行節流控制?當用戶拖動滾動條完畢後,再查詢新的內容?但這與需求不符,用戶但願在拖動的過程當中也能看到新內容的變化。
所以咱們決定這樣作:用戶在拖動時,每兩次查詢的間隔很多於500毫秒,若是用戶拖動了1秒鐘,這可能會觸發200次onscroll事件,但咱們最多隻進行2次查詢。
利用Underscore中的throttle()方法,咱們也能夠輕鬆實現這個需求:
<script type="text/javascript">
var query = _(function() {
// 在這裏進行查詢操做
}).throttle(500);
$(window).bind('scroll', query);
</script>
代碼仍然十分簡潔,由於在throttle()方法內部,已經爲咱們實現的全部控制。
你可能已經發現,debounce()和throttle()兩個方法很是類似(包括調用方式和返回值),做用卻又有不一樣。
它們都是用於函數節流,控制函數不被頻繁地調用,節省客戶端及服務器資源。
debounce()方法關注函數執行的間隔,即函數兩次的調用時間不能小於指定時間。
throttle()方法更關注函數的執行頻率,即在指定頻率內函數只會被調用一次。