JS節流和防抖的區分和實現詳解
關於JS中比較常用的函式:節流函式和防抖函式,從概念、使用場景到程式碼簡單實現做了一個詳細的區分。希望對你有所幫助。
在寫JS時,這兩個函式比較常見,有時候傻傻分不清用哪個,或者說知道程式碼要怎麼寫,但要說出它究竟是節流函式還是防抖函式時一臉楞逼。今天有一個同學分享了這兩個的區分,我也來回顧一下,加深一下印象,以便日後用到時心裡有底。PS:百度和谷歌搜尋前幾個介紹都是相反介紹,本文為原創,如有雷同純屬抄襲我的。
節流概念(Throttle)
按照設定的時間固定執行一次函式,比如200ms一次。注意:固定就是你在mousemove過程中,執行這個節流函式,它一定是200ms(你設定的定時器延遲時間)內執行一次。沒到200ms,一定會返回,沒有執行回撥函式的。
主要應用場景有:scroll、touchmove
防抖概念(Debounce)
抖動停止後的時間超過設定的時間時執行一次函式。注意:這裡的抖動停止表示你停止了觸發這個函式,從這個時間點開始計算,當間隔時間等於你設定時間,才會執行裡面的回撥函式。如果你一直在觸發這個函式並且兩次觸發間隔小於設定時間,則一定不會到回撥函式那一步。
主要應用場景有:input驗證、搜尋聯想、resize
節流實現
思路: 第一次先設定一個變數true,第二次執行這個函式時,會判斷變數是否true,是則返回。當第一次的定時器執行完函式最後會設定變數為flase。那麼下次判斷變數時則為flase,函式會依次執行。
程式碼一:首次不執行
function throttle(fn,delay=100){ //首先設定一個變數,在沒有執行我們的定時器時為null let timer = null; return function(){ //當我們發現這個定時器存在時,則表示定時器已經在執行中,需要返回 if(timer) return; timer = setTimeout(()=>{ fn.apply(this,arguments); timer = null; },delay); } }
程式碼二:首次執行
function throttle2(fn,delay=100){ let last = 0; return function(){ let curr = +new Date(); if(curr - last > delay){ fn.apply(this,arguments); last = curr; } } }
防抖實現
思路:首次執行時把定時器賦值給一個變數,第二次執行時,如果間隔沒超過定時器設定的時間則會清除掉定時器,重新設定定時器,依次反覆,當我們停止下來時,沒有執行清除定時器,超過一定時間後觸發回撥函式。
程式碼一:首次不執行
function debounce(fn,delay=200){ let timer = null; return function(){ if(timer) clearTimeout(timer); timer = setTimeout(()=>{ fn.apply(this,arguments); timer = null; },delay); } }
程式碼二:首次執行
function debounce2(fn, delay = 200, atBegin = true) { let timer = null, last = 0,during; return function () { let self = this, args = arguments; var exec = function () { fn.apply(self, args); } if (atBegin && !timer) { exec(); atBegin = false; } else { during = Date.now() - last; if (during > delay) { exec(); } else { if (timer) clearTimeout(timer); timer = setTimeout(function () { exec(); }, delay); } } last = Date.now(); } }
開啟控制檯觀察變化
上面的程式碼只是我自己的一個簡單實現,看看lodash裡面的兩個核心實現程式碼。生產中建議使用它們的庫,畢竟有這麼多人在用,出bug的機會比較少,我上面的程式碼有可能有一些情況沒考慮到。如果你發現有問題的,也請告訴我。
如果在專案中有需要用到的,可以直接安裝單個的NPM模組。 和
lodash使用使用文件
lodash庫裡面這兩個函式設定的引數有點複雜,記錄一下里面的引數和程式碼使用。
節流(throttle)
官方文件解釋:
建立一個節流函式,在 wait 秒內最多執行 func 一次的函式。 該函式提供一個 cancel 方法取消延遲的函式呼叫以及 flush 方法立即呼叫。 可以提供一個 options 物件決定如何呼叫 func 方法, options.leading 與|或 options.trailing 決定 wait 前後如何觸發。 func 會傳入最後一次傳入的引數給這個函式。 隨後呼叫的函式返回是最後一次 func 呼叫的結果。
注意: 如果 leading 和 trailing 都設定為 true 則 func 允許 trailing 方式呼叫的條件為: 在 wait 期間多次呼叫。
如果 wait 為 0 並且 leading 為 false, func呼叫將被推遲到下一個點,類似setTimeout為0的超時。
引數
func (Function) 要節流的函式 [wait=0] (number) 需要節流的毫秒 [options] (Object) 選項物件 [options.leading=true] (boolean) 指定呼叫在節流開始前 [options.trailing=true] (boolean) 指定呼叫在節流結束後
返回值 (Function)
返回節流的函式
示例
// 避免在滾動時過分的更新定位 jQuery(window).on('scroll', _.throttle(updatePosition, 100)); // 點選後就呼叫 `renewToken`,但5分鐘內超過1次。 var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); jQuery(element).on('click', throttled); // 取消一個 trailing 的節流呼叫 jQuery(window).on('popstate', throttled.cancel);
防抖(debounce)
建立一個 debounced(防抖動)函式,該函式會從上一次被呼叫後,延遲 wait 毫秒後呼叫 func 方法。 debounced(防抖動)函式提供一個 cancel 方法取消延遲的函式呼叫以及 flush 方法立即呼叫。 可以提供一個 options(選項) 物件決定如何呼叫 func 方法,options.leading 與 options.trailing 決定延遲前後如何觸發(先呼叫後等待 還是 先等待後呼叫)。 func 呼叫時會傳入最後一次提供給 debounced(防抖動)函式 的引數。 後續呼叫的 debounced(防抖動)函式返回是最後一次 func 呼叫的結果。
注意: 如果 leading 和 trailing 選項為 true, 則 func 允許 trailing 方式呼叫的條件為: 在 wait 期間多次呼叫防抖方法。
如果 wait 為 0 並且 leading 為 false, func呼叫將被推遲到下一個點,類似setTimeout為0的超時。
引數
<pre>//code from `func (Function) 要防抖動的函式 [wait=0] (number) 需要延遲的毫秒數 [options] (Object) 選項物件 [options.leading=false] (boolean) 指定呼叫在延遲開始前 [options.maxWait] (number) 設定 func 允許被延遲的最大值 [options.trailing=true] (boolean) 指定呼叫在延遲結束後` </pre>
返回值 (Function)
返回具有防抖動功能的函式
示例
// 避免視窗在變動時出現昂貴的計算開銷。 jQuery(window).on('resize', _.debounce(calculateLayout, 150)); // 當點選時 `sendMail` 隨後就被呼叫。 jQuery(element).on('click', _.debounce(sendMail, 300, { 'leading': true, 'trailing': false })); // 確保 `batchLog` 呼叫1次之後,1秒內會被觸發。 var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); var source = new EventSource('/stream'); jQuery(source).on('message', debounced); // 取消一個 trailing 的防抖動呼叫 jQuery(window).on('popstate', debounced.cancel);
以上就是節流和防抖的全部介紹
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901074/viewspace-2636317/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師分享JS節流和防抖的區分和實現詳解程式設計師JS
- js防抖和節流的區別及實現方式JS
- JS簡單實現防抖和節流JS
- js防抖和節流JS
- 影片直播原始碼,js實現節流和防抖原始碼JS
- js 函式防抖和節流JS函式
- js防抖 和節流函式JS函式
- 防抖和節流
- 防抖和節流的應用場景和實現
- js函式中的節流和防抖JS函式
- 防抖與節流的區別與實現
- js函式防抖debounce和節流throttleJS函式
- JS函式節流和函式防抖JS函式
- 函式的防抖和節流函式
- 函式防抖和節流函式
- 防抖和節流原理分析
- 函式節流和防抖函式
- 區分函式防抖&函式節流函式
- 一道筆試題:利用JS程式碼實現防抖和節流筆試JS
- 淺談js函式節流和函式防抖JS函式
- UnderScore原始碼看防抖和節流原始碼
- 效能優化之防抖和節流優化
- JavaScript專題系列-防抖和節流JavaScript
- 函式防抖和函式節流函式
- 固定表頭和首列,防抖節流
- 關於js節流函式throttle和防抖動debounceJS函式
- 輕鬆理解JS函式節流和函式防抖JS函式
- js優化之防抖節流JS優化
- 防抖動處理和節流 小技巧
- 蝦扯蛋之函式防抖和節流函式
- 例項解析防抖動和節流閥
- 簡單介紹JS函式防抖和函式節流JS函式
- 7分鐘理解JS的節流、防抖及使用場景JS
- [譯]例項詳解防抖與節流(乾貨!!!)
- 前端都應該要掌握的防抖和節流前端
- JavaScript淺析 -- 定時器和節流防抖JavaScript定時器
- [手寫系列] Spirit帶你實現防抖函式和節流函式函式
- 防抖和節流及對應的React Hooks封裝ReactHook封裝