函數節流和函數防抖前端
函數節流和函數防抖兩者很容易被混淆起來。下面貼英文原文,建議認真閱讀:
Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called".
Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds".ajax
函數節流:確保函數特定的時間內至多執行一次。
函數防抖:函數在特定的時間內不被再調用後執行。瀏覽器
上面的概念可能仍是不夠清晰,下面均以「輸入框輸入文字觸發ajax獲取數據」爲例,分別以防抖和節流的思想來優化,兩者的區別:性能優化
輸入框輸入文字以下:1111111111111111111111(停頓3s繼續輸入)11111111111111111
函數防抖:當用戶持續輸入1的過程當中,並不會發送ajax,當用戶中止輸入2s後,發送ajax請求,以後到第3s後,用戶繼續輸入1的過程當中,依舊不會發送ajax,當用戶中止輸入2s後,又觸發ajax請求。
函數節流:當用戶持續輸入1的過程當中(假設輸入1的過程超過2s了),從你開始輸入1開始計時,到第2s,發送ajax請求。函數節流與你是否中止輸入無關,是一種週期性執行的策略。
一句話歸納:函數節流是從用戶開始輸入就開始計時,而函數節流是從用戶中止輸入開始計時。app
場景分析前端性能
函數節流(throttle)函數
函數防抖(debounce)性能
注:throttle和debounce均是經過減小實際邏輯處理過程的執行來提升事件處理函數運行性能的手段,並無實質上減小事件的觸發次數。優化
使用函數節流是進行前端性能優化的方法之一,例如,懶加載的實現。this
實現函數防抖和函數節流
函數防抖
function debounce(func,wait){ var timeout; return function(){ var context=this;//用來保存this的正確指向 var args=arguments;//用來保存觸發的事件類型,例如keyboard event clearTimeout(timeout);//每次都從新開始計時 timeout=setTimeout(function(){ func.apply(context,args); },wait); } } a.onkeyup=debounce(getValue,3000); function getValue(){ console.log(this.value);//使用debounce調用它時,this就變爲window }
函數節流
function throttle(func, wait) { var timeout, context, args, result; var previous = 0; var later = function() { previous = +new Date(); timeout = null; func.apply(context, args) }; var throttled = function() { var now = +new Date(); //下次觸發 func 剩餘的時間 var remaining = wait - (now - previous); context = this; args = arguments; // 若是沒有剩餘的時間了或者你改了系統時間 if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } }; return throttled; }