什么是防抖與節流
防抖節流一般都放在一起說,隨便一搜都是兩者的解釋與區別,這里就不copy了,僅記錄我自己的理解。
兩者都是針對高頻函數做的優化,記住其中一個,另一個就知道了。一個是time內只執行一次;另一個是延遲time后執行一次,若time內再次被執行,重頭計算time。
簡而言之,節流相當於游戲的技能冷卻,用過一次后cd時間內不能再用,防抖有種隨着高頻操作的進行不斷延遲函數執行的感覺,想要執行必須要停下等time過了才可以。
兩者均有典型的應用例子,比如節流經常用在滾動監聽中,防抖經常用在輸入框搜索中。
節流在項目中的應用場景
項目是學生搶課,用戶選中課之后點擊提交,等待回饋結果,在等待過程中,用戶難免會不停的點擊提交按鈕,或者不停的刷新頁面,難道請求也一直隨着點擊發送嗎,當然不可,本就是高並發請求,這樣會給后端造成巨大的壓力。
那是做點擊防抖還是點擊節流呢?
做點擊節流。
逆向思維想一下,若是做防抖的話,用戶一直點,豈不是一直不發送請求?根據實際情況,這里選擇做點擊節流。
節流函數代碼
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function throttle(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function() { // 據上一次觸發時間間隔 const last = +new Date() - timestamp // 上次被包裝函數被調用時間間隔 last 小於設定時間間隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果設定為immediate===true,因為開始邊界已經調用過了此處無需調用 if (!immediate) { result = func.call(context, args) if (!timeout) context = args = null } } } return function(...args) { context = this timestamp = +new Date() const callNow = immediate && !timeout // 如果延時不存在,重新設定延時 if (!timeout) timeout = setTimeout(later, wait) if (callNow) { result = func.apply(context, args) context = args = null } return result } }
節流函數使用
<button @click="submit">提交</button>
import {throttle}from "寫節流函數的文件地址"
submit:debounce(function(a,b,c){ //業務邏輯
},lateTime,true)
自行研究出現的問題(所貼代碼中已解決)
發現函數內的this無效,函數的this已經被用了,節流函數內賦值一下就可以了。
發現函數參數無效,funct.call(_this,...arguments)和funct.apply(_this,argus)用混了。
防抖函數代碼
/** * @param {Function} fun * @param {number} wait */ export function debounce(fun,wait){
let timer,_this; return function (){ _this = this; if(timer){ clearTimeout(timer) } timer = setTimeout(()=>{ fun.call(_this,...arguments); },wait) } }
防抖函數使用跟節流一樣