javascript
JavaScript函数节流(throttle)与函数去抖(debounce)解析与应用举例
概念
函數(shù)防抖(debounce):
事件響應函數(shù)在一段時間后才會執(zhí)行,如果在這段時間內再次調用,則重新計算執(zhí)行時間;當預定時間內沒有再次調用該函數(shù),則執(zhí)行響應邏輯。
函數(shù)節(jié)流(throttle):
可以理解為在函數(shù)防抖上多加了一個功能:函數(shù)節(jié)流會預定一個自動執(zhí)行時間,到時自動執(zhí)行一次。
共同點:
函數(shù)節(jié)流與函數(shù)防抖都是為了限制函數(shù)的執(zhí)行頻次,是一種性能優(yōu)化的方案,比如應用于window對象的resize、scroll事件,拖拽時的mousemove事件,文字輸入、自動完成的keyup事件。
舉例
以百度搜索為例:用戶搜索輸入時,邊輸入會邊提示搜索內容,如下:
從網(wǎng)絡請求來看,百度是監(jiān)聽了鍵盤輸入,按一次鍵就發(fā)一次請求,如下:
對于百度來說,這樣自然沒什么問題,畢竟服務器強大,這點消耗不算什么,但在我們看來,有什么可以優(yōu)化的呢?
方案一:在用戶沒有輸入的m毫秒后再發(fā)送請求(函數(shù)去抖)
方案二:在用戶沒有輸入的m毫秒后再發(fā)送請求,但期間每隔n毫秒會自動發(fā)一次請求(函數(shù)節(jié)流)
函數(shù)去抖實現(xiàn)
實現(xiàn)用戶停止輸入1秒后開始發(fā)送搜索請求,以下實現(xiàn)不注重樣式,僅實現(xiàn)需求。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>函數(shù)去抖</title> </head> <body><h4>函數(shù)去抖實現(xiàn)</h4><input type="text"><div class="show"></div> </body> <script>var input = document.getElementsByTagName('input')[0]input.addEventListener('keyup', function () {debounce(doSearch, window, this.value)})function doSearch (searchText) {var p = document.createElement('p')p.innerText = '當前搜索內容: ' + searchTextdocument.getElementsByClassName('show')[0].appendChild(p)}function debounce (fn, context, searchText) {clearTimeout(this.timer) // 關鍵點:1000ms內重復調用則清除timerthis.timer = setTimeout(function() { fn.call(context, searchText) // 調用函數(shù)fn,context為fn所屬作用域}, 1000) } </script> </html>運行結果:
函數(shù)節(jié)流實現(xiàn)
以下實現(xiàn)用戶停止輸入2秒后發(fā)搜索請求,期間每隔500ms發(fā)一次搜索請求。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>函數(shù)節(jié)流</title> </head> <body><h4>函數(shù)節(jié)流實現(xiàn)</h4><input type="text"><div class="show"></div> </body> <script>var input = document.getElementsByTagName('input')[0]input.addEventListener('keyup', function() {throttle(doSearch, window, this.value, 500, 2000)})function doSearch (searchText) {var p = document.createElement('p')p.innerText = '當前搜索內容: ' + searchTextdocument.getElementsByClassName('show')[0].appendChild(p)}// (調用方法, 方法所屬對象, 自動執(zhí)行時間, 最大延遲執(zhí)行時間 ))function throttle (fn, context, searchText, autoDoTime, delay) {clearTimeout(fn.timer)// 記錄當前時間fn.currentTime = Date.now()// 若該函數(shù)是第一次調用,則直接設置startTime,即開始時間,為currentTime,即此刻的時間if(!fn.startTime){ fn.startTime = fn.currentTime}// 大于等于自動執(zhí)行時間,調用方法if(fn.currentTime - fn.startTime >= autoDoTime){fn.call(context, searchText)fn.startTime = fn.currentTime} else {// 大于最大延遲時間,調用方法fn.timer = setTimeout(function(){fn.call(context, searchText)}, delay)}} </script> </html>運行結果:
相關解釋請參考代碼中的注釋。
總結
以上是生活随笔為你收集整理的JavaScript函数节流(throttle)与函数去抖(debounce)解析与应用举例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 米哈游《原神》韩国线下活动遭炸弹威胁而中
- 下一篇: 日本航天公司 Interstella 计