何謂節流和防抖?
節流
節流的意思是,規定時間內,只觸發一次。比如我們設定500ms,在這個時間內,無論點擊按鈕多少次,它都只會觸發一次。具體場景可以是搶購時候,由於有無數人 快速點擊按鈕,如果每次點擊都發送請求,就會給服務器造成巨大的壓力,但是我們進行節流后,就會大大減少請求的次數。
防抖
防抖的意思是,在連續的操作中,無論進行了多長時間,只有某一次的操作后在指定的時間內沒有再操作,這一次才被判定有效。具體場景可以搜索框輸入關鍵字過程中實時 請求服務器匹配搜索結果,如果不進行處理,那么就是輸入框內容一直變化,導致一直發送請求。如果進行防抖處理,結果就是當我們輸入內容完成后,一定時間(比如500ms)沒有再 輸入內容,這時再觸發請求。
結合以上兩種情況,回到我們最實際的場景,比如防止表單提交按鈕被多次觸發,我們應該選擇使用節流
而不是防抖
方案。
防抖debounceTail
只執行首次 // 防抖 且首次執行 // 采用原理:第一操作觸發,連續操作時,最后一次操作打開任務開關(並非執行任務),任務將在下一次操作時觸發) function debounceStart(fn, delay, ctx) { let immediate = true let movement = null return function() { let args = arguments // 開關打開時,執行任務 if (immediate) { fn.apply(ctx, args) immediate = false } // 清空上一次操作 clearTimeout(movement) // 任務開關打開 movement = setTimeout(function() { immediate = true }, delay) } } 只執行最后一次 // 防抖 尾部執行 // 采用原理:連續操作時,上次設置的setTimeout被clear掉 function debounceTail(fn, delay, ctx) { let movement = null return function() { let args = arguments // 清空上一次操作 clearTimeout(movement) // delay時間之后,任務執行 movement = setTimeout(function() { fn.apply(ctx, args) }, delay) } }
節流函數throttle
// 節流方案1,每delay的時間執行一次,通過開關控制 function throttle(fn, delay, ctx) { let isAvail = true return function () { let args = arguments // 開關打開時,執行任務 if (isAvail) { fn.apply(ctx, args) isAvail = false // delay時間之后,任務開關打開 setTimeout(function () { isAvail = true }, delay) } } } // 節流方案2,通過計算開始和結束時間 function throttle(fn,delay){ // 記錄上一次函數出發的時間 var lastTime = 0 return function(){ // 記錄當前函數觸發的時間 var nowTime = new Date().getTime() // 當當前時間減去上一次執行時間大於這個指定間隔時間才讓他觸發這個函數 if(nowTime - lastTime > delay){ // 綁定this指向 fn.call(this) //同步時間 lastTime = nowTime } } }
詳見 “uview開發文檔防抖與節流” 部分右邊用例狂點幾下就明白了