概念:
函數防抖(debounce):觸發高頻事件后n秒內函數只會執行一次,如果n秒內高頻事件再次被觸發,則重新計算時間。
函數節流(throttle):高頻事件觸發,但在n秒內只會執行一次,所以節流會稀釋函數的執行頻率。
函數節流(throttle)與 函數防抖(debounce)都是為了限制函數的執行頻次,以優化函數觸發頻率過高導致的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象。
防抖:
- 實現方式:每次觸發事件時設置一個延遲調用方法,並且取消之前的延時調用方法
- 缺點:如果事件在規定的時間間隔內被不斷的觸發,則調用方法會被不斷的延遲
/* 1. 防抖: 實現方式:每次觸發事件時設置一個延遲調用方法,並且取消之前的延時調用方法 缺點:如果事件在規定的時間間隔內被不斷的觸發,則調用方法會被不斷的延遲 */ function debounce(fn, delay) { // 創建一個標記來存放定時器的返回值 var timeout = null; return function (e) { // 每當用戶操作時,把之前的計時器清零
if(timeout !== null) {
clearTimeout(timeout);
}
// 然后又創建一個新的 setTimeout, 這樣就能保證interval 間隔內如果時間持續觸發,就不會執 行 fn 函數 timeout = setTimeout(() => { fn.apply(this, arguments); }, delay) } } // 處理函數 function handle() { console.log('防抖:', Math.random()); } //點擊事件 window.addEventListener('click', debounce(handle, 500));
函數節流(throttle)
- 實現方式:時間戳和定時器
// 時間戳 var throttle = function (func, delay) { var prev = Date.now(); return function () { var context = this; var args = arguments; var now = Date.now(); if (now - prev >= delay) { func.apply(context, args); prev = Date.now(); } } } //定時器 // 節流throttle代碼(定時器): var throttle = function (func, delay) { var timer = null; return function () { var context = this; var args = arguments; if (!timer) { timer = setTimeout(function () { func.apply(context, args); timer = null; }, delay); } } } // (時間戳+定時器) // 節流throttle代碼(時間戳+定時器): var throttle = function (func, delay) { var timer = null; var startTime = Date.now(); return function () { var curTime = Date.now(); var remaining = delay - (curTime - startTime); var context = this; var args = arguments; clearTimeout(timer); if (remaining <= 0) { func.apply(context, args); startTime = Date.now(); } else { timer = setTimeout(func, remaining); } } } function sayHi() { console.log('節流:', Math.abs(22.22)); } window.addEventListener('click', throttle(sayHi, 1000));
總結:
函數防抖:將多次操作合並為一次操作進行。原理是維護一個計時器,規定在delay時間后觸發函數,但是在delay時間內再次觸發的話,就會取消之前的計時器而重新設置。這樣一來,只有最后一次操作能被觸發。
函數節流:使得一定時間內只觸發一次函數。原理是通過判斷是否有延遲調用函數未執行。
區別: 函數節流不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數,而函數防抖只是在最后一次事件后才觸發一次函數。 比如在頁面的無限加載場景下,我們需要用戶在滾動頁面時,每隔一段時間發一次 Ajax 請求,而不是在用戶停下滾動頁面操作時才去請求數據。這樣的場景,就適合用節流技術來實現。
參考:
https://www.cnblogs.com/momo798/p/9177767.html
https://blog.csdn.net/zuorishu/article/details/93630578