天天看點

函數節流與防抖的實作

節流:

高頻事件不斷觸發,每隔一定時間會執行一次,會稀釋高頻事件;

實作原理:在閉包内設定一個标記,初始值為true,若标記為false,則退出函數,不執行,若标記值為true,馬上将标記變成false;并且執行一個定時器,在定時器内執行回調函數,并且将标記設定為true;

具體代碼:

function throttle(fn,time){
      var canrun = true;//通過閉包儲存一個标記
      return function(){//傳回一個函數
        if(!canrun) return;//如果不在執行時間内 則不執行
        canrun = false;//如果在執行時間内 馬上将标記改為false 然後執行後續代碼
        setTimeout(() => {
          // 執行時間結束時 執行函數 并且将标記設定為可執行
          fn.apply(this,arguments);
          canrun = true;
        },time);
      };
    }      

測試代碼:

let dom = document.getElementsByClassName("content")[0];
    var log2 = throttle(log,2000);//把log函數變成一個節流函數
    dom.addEventListener("click",function(){
      log2(222);
    })
    function log(num){
      console.log(num);
    }      

防抖:

高頻事件觸發時,在一定時間内函數隻會觸發一次,如果不停觸發,那麼久隻執行一次,不會隔一段時間執行一次,除非中間停止足夠的時間,才會觸發第二次;

實作原理:在閉包内定義一個變量,次變量用來存放定時器,執行函數時會先清除上一個定時器,然後重新設定一個定時器,定時器内執行回調函數,如果一直觸發,就會不斷的清除計時器,函數就不會執行;

function debounce(fn,time){
      let timeout = null;
      return function(){
        clearTimeout(timeout); //清除定時器 定時器清除後,内部的函數就不會執行
        timeout = setTimeout(() => {//重新設定定時器
          fn.apply(this,arguments);//執行函數
        }, time);
      }
    }      
let dom = document.getElementsByClassName("content")[0];
    var log2 = debounce(log,2000);//把log函數變成防抖函數
    dom.addEventListener("click",function(){
      log2(222);
    })
    function log(num){
      console.log(num);
    }