JS實現節流與防抖


概念:

函數防抖(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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM