JS之函數防抖與節流

1、函數防抖

原理:函數執行過一次後,在等待時間段內不能再次執行。 在等待時間內觸發此函數,則重新計算等待時間。

代碼實現

    /*
    *fn:要防抖的函數
    *wait:要等待的時間
    *immediate:是否立刻執行fn函數
    */
    function debounce(fn,wait,immediate){
        let timer=null; 
        let _debounce=function(){
            //判斷定時器是否存在,存在即刪除定時器
            timer&&clearTimeOut(timer);
            //是否立刻執行
            if(immediate){
                //定時器不存在時,纔回去執行函數
                !timer&&fn.apply(this,...arruments)
                timer=setTimeOut(()={
                    timer=null;
                    //過了await時間後,fn纔可以被再次執行
                },await)
            }else{
                timer=setTimeOut(()=>{
                    //過了await時間後,再次設置的定時器纔不會被清除
                    timer=null;
                    fn.apply(this,...arguments);
                    //arguments爲調用fn函數傳入的參數
                },await)
            }
        }
        //取消
        _debounce.cancel=()=>{
            timer=null;
            clearTimeOut(timer);
        }
        return _debounce;
    }
    //應用
    window.onscroll = _debounce(function(){
        console.log(1);
    }, 500, true);

應用場景:

  • 每次 resize/scroll 觸發統計事件
  • 文本輸入驗證(連續輸入文字後發生ajax請求進行驗證,驗證一次就好)
  • mousemovemousedown
  • 加載更多

 

2、函數節流

原理:節流就是在讓函數在特定的時間內只執行一次(持續觸發事件,每隔一段時間,只執行一次事件)。

代碼實現

function throtle(fn,await){
    let timer=null;
    let previousTime=0;
    let _throtle=()=>{
        let now=+new Date();//獲取當前時間戳
        let remain=now-previousTime
        if(remain>await){
            //下面的代碼只會在第一次觸發時執行(或者是間隔時間超過await後再次執行)
            if(timer){
                //清除定時器
                clearTimeOut(timer);
                timer=null
            }
            //此時now不等於+new Date()
            previousTime=+new Date();//當前時間,使用+獲取當前時間戳
            fn.apply(this,...arguments);
        }else if(!timer){//避免添加多個定時器
            timer=setTimeOut(()=>{
               timer=null;
               previousTime=+new Date();//當前時間
               fn.apply(this,...arguments);
            },remain);
        }
    }
    _throtle.cancel=()=>{
        timer=null;
        clearTimeOut(timer);
        previousTime=0;
    }
    return _throtle;
}

應用場景:

  • 每次 resize觸發統計事件
  • mousemove
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章