白话debounce和throttle
遇到的問題
在開發過程中會遇到頻率很高的事件或者連續的事件,如果不進行性能的優化,就可能會出現頁面卡頓的現象,比如:
為了解決這類問題,常常使用的方法就是throttle(節流)和debounce(去抖)。throttle(節流)和debounce(去抖)都是用來控制某個函數在一定時間內執行多少次的解決方案,兩者相似而又不同。
下面就具體的看看兩者的相似和區別。
認識throttle和debounce
throttle和debounce的作用就是確認事件執行的方式和時機,以前總是不太清楚兩者的區別,容易把二者弄混。
下面就通過兩個簡單的場景描述一下debounce和throttle,以后想到這兩個場景就不會再弄混了:
debounce 假設你正在乘電梯上樓,當電梯門關閉之前發現有人也要乘電梯,禮貌起見,你會按下開門開關,然后等他進電梯; 如果在電梯門關閉之前,又有人來了,你會繼續開門; 這樣一直進行下去,你可能需要等待幾分鐘,最終沒人進電梯了,才會關閉電梯門,然后上樓。所以debounce的作用是,當調用動作觸發一段時間后,才會執行該動作,若在這段時間間隔內又調用此動作則將重新計算時間間隔。
throttle 假設你正在乘電梯上樓,當電梯門關閉之前發現有人也要乘電梯,禮貌起見,你會按下開門開關,然后等他進電梯; 但是,你是個沒耐心的人,你最多只會等待電梯停留一分鐘; 在這一分鐘內,你會開門讓別人進來,但是過了一分鐘之后,你就會關門,讓電梯上樓。所以throttle的作用是,預先設定一個執行周期,當調用動作的時刻大于等于執行周期則執行該動作,然后進入下一個新的時間周期。
簡單實現
有了上面的了解,就可以去實現簡單debounce和throttle了。
debounce實現
首先來看看debounce的實現,根據前面對debounce的描述:
可以在Chrome中運行下面的代碼,看看debounce的效果,代碼Github鏈接:
var debounce = function(action, delay) {var timer = null; return function() { var self = this, args = arguments; clearTimeout(timer); timer = setTimeout(function() { action.apply(self, args) }, delay); } } // example function resizeHandler() { console.log("resize"); } window.onresize = debounce(resizeHandler, 300);throttle實現
throttle跟debounce的最大不同就是,throttle會有一個閥值,當到達閥值的時候action必定會執行一次。
所以throttle的實現可以基于前面的debounce的實現,只需要加上一個閥值,代碼Github鏈接:
var throttleV1 = function(action, delay, mustRunDelay) {var timer = null, startTime; return function() { var self = this, args = arguments, currTime = new Date(); clearTimeout(timer); if(!startTime) { startTime = currTime; } if(currTime - startTime >= mustRunDelay) { action.apply(self, args); startTime = currTime; } else { timer = setTimeout(function() { action.apply(self, args); }, delay); } }; };其實,對于上面的實現可以進心簡化,只是通過閉包維護一個開始的時間:
var throttleV2 = function(action, delay){var statTime = 0; return function() { var currTime = +new Date(); if (currTime - statTime > delay) { action.apply(this, arguments); statTime = currTime ; } } } // example function resizeHandler() { console.log("resize"); } window.onresize = throttleV2(resizeHandler, 300);總結
通過前面的介紹,應該對debounce和throttle有一個直觀的認識了:
- debounce:把觸發非常頻繁的事件合并成一次執行
- throttle:設置一個閥值,在閥值內,把觸發的事件合并成一次執行;當到達閥值,必定執行一次事件
了解了throttle和debounce之后,下面看看他們的常用場景:
debounce
- 對于鍵盤事件,當用戶輸入比較頻繁的時候,可以通過debounce合并鍵盤事件處理
- 對于ajax請求的情況,例如當頁面下拉超過一定返回就通過ajax請求新的頁面內容,這時候可以通過debounce合并ajax請求事件
throttle
-
對于鍵盤事件,當用戶輸入非常頻繁,但是我們又必須要在一定時間內(閥值)內執行處理函數的時候,就可以使用throttle
- 例如,一些網頁游戲的鍵盤事件
-
對于鼠標移動和窗口滾動,鼠標的移動和窗口的滾動會帶來大量的事件,但是在一段時間內又必須看到頁面的效果
- 例如對于可以拖動的div,如果使用debounce,那么div會在拖動停止后一下子跳到目標位置;這時就需要使用throttle
轉載于:https://www.cnblogs.com/gluncle/p/9945009.html
總結
以上是生活随笔為你收集整理的白话debounce和throttle的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用docker部署mysql主从复制集
- 下一篇: kali:用TheFatRat攻击win