概念和例子
函數防手震(debounce)
在事件觸發n秒後再執行回調,如果在這n秒內又被觸發,則重新計時。
看一個(栗子):
//模拟一段ajax请求 function ajax(content) { console.log('ajax request ' + content) } let inputa = document.getElementById('unDebounce') inputa.addEventListener('keyup', function (e) { ajax(e.target.value) })
複製程式碼看一下運行結果:
可以看到,我們只要按下鍵盤,就會觸發這次ajax請求。不僅從資源上來說是很浪費的行為,而且實際應用中,使用者也是輸出完整的字元後,才會請求。下面我們優化一下:
//模拟一段ajax请求 function ajax(content) { console.log('ajax request ' + content) } function debounce(fun, delay) { return function (args) { let that = this let _args = args clearTimeout(fun.id) fun.id = setTimeout(function () { fun.call(that, _args) }, delay) } } let inputb = document.getElementById('debounce') let debounceAjax = debounce(ajax, 500) inputb.addEventListener('keyup', function (e) { debounceAjax(e.target.value) })
複製程式碼看看運行結果:
可以看到,我們加入了防手震以後,當你在頻繁的輸入時,並不會發送請求,只有當你在指定間隔內沒有輸入時,才會執行函數。如果停止輸入但是在指定間隔內又輸入,會重新觸發計時。
再看一個:
let biu = function () { console.log('biu biu biu',new Date().Format('HH:mm:ss')) } let boom = function () { console.log('boom boom boom',new Date().Format('HH:mm:ss')) } setInterval(debounce(biu,500),1000) setInterval(debounce(boom,2000),1000)
複製程式碼看一下運行結果:
#這個就很好的解釋了,如果在時間間隔內執行函數,會重新觸發計時。 biu會在第一次1.5s執行後,每隔1s執行一次,而boom一次也不會執行。因為它的時間間隔是2s,而執行時間是1s,所以每次都會重新觸發計時
個人理解函數防手震就是法師發技能的時候要讀條,技能讀條沒完再按技能就會重新讀條。
函數節流(throttle)
規定在一個單位時間內,只能觸發一次函數。如果這個單位時間內觸發多次函數,只有一次生效。
看一個:
function throttle(fun, delay) { let last, deferTimer return function (args) { let that = this let _args = arguments let now = +new Date() if (last && now < last + delay) { clearTimeout(deferTimer) deferTimer = setTimeout(function () { last = now fun.apply(that, _args) }, delay) }else { last = now fun.apply(that,_args) } } } let throttleAjax = throttle(ajax, 1000) let inputc = document.getElementById('throttle') inputc.addEventListener('keyup', function(e) { throttleAjax(e.target.value) })
複製程式碼看一下運行結果:
#可以看到,當我們不斷輸入時,ajax會按照我們設定的時間,每1s執行一次。
結合剛剛biubiubiu的:
let biubiu = function () { console.log('biu biu biu', new Date().Format('HH:mm:ss')) } setInterval(throttle(biubiu,1000),10)
#不管我們設定的執行時間間隔多小,總是1s內只執行一次。
個人理解 函數節流就是fps遊戲的射速,就算一直按著滑鼠射擊,也只會在規定射速內射出子彈。
總結
函數防手震和函數節流都是防止某一時間頻繁觸發,但是這兩兄弟之間的原理卻不一樣。
函數防手震是某一段時間只執行一次,而函數節流是間隔時間執行。
結合應用程式場景
debounce
#search搜尋聯想,使用者在不斷輸入值時,用防手震來節約請求資源。
window觸發resize的時候,不斷的調整瀏覽器視窗大小會不斷的觸發這個事件,用防抖來讓其只觸發一次
throttle
滑鼠不斷點選觸發,mousedown(單位時間內只觸發一次)
監聽捲動事件,例如是否滑到底部自動載入更多,用throttle來判斷
以上是JS的防手震與節流的詳細內容。更多資訊請關注PHP中文網其他相關文章!