函式的防抖與節流

jilaokang發表於2018-10-10

函式的防抖與節流目的都是在於減少事件呼叫頻率

防抖場景:搜尋場景,待使用者停頓進行檢測。

節流場景:驗證碼場景,60秒內不可以再次點選。

防抖與節流的區別

在多次連續執行中,防抖是執行最後一次,節流是執行第一次。比如上面我們提到的搜尋就是檢測使用者最後輸入值,驗證碼就是使用者的第一次點選。

防抖

在前面的事件還沒有執行完畢,又有了新的事件,那麼取消前面的事件,執行新的事件。

var debounce = (fn, wait) => {
    let timer = null
    
    return (...value) => {
        // 如果前面有待執行的timer,清除timer
        if(timer) clearTimeout(timer)

        // 構建最新的timer,放入執行佇列
        timer = setTimeout(()=>{
            fn(value)
        }, wait)        
    }
}
複製程式碼

防抖升級:我們知道按照上面的話,我們在第一次輸入的時候就要進行等待,這是沒有必要的也影響到使用者體驗。 可以優化成:使用者首次輸入,執行不用等待->繼續輸入,進入防抖->抖動結束返回第一步


var debounce = (fn, wait) => {
  let timer;
  let first = true;

  return (...value) => {
    if (first) {
      first = false;
      return fn(value);
    }

    if (timer) clearTimeout(timer);

    timer = setTimeout(() => {
      fn(value);
      first = true;
    }, wait);
  };
};

let con = (...val) => console.log(...val);
let conPlus = debounce(con, 2000);

conPlus("frist");
conPlus("second");
conPlus("last");
複製程式碼

節流

在前面的事件沒有執行完畢,狀態固定為不可執行,待執行完畢後更新狀態。

var throttle = (fn, wait) => {
    let canRun = true
    
    return (...value) => {
        // 檢測狀態,鎖住狀態則不可二次執行
        if(canRun === false){
            return 
        }
        
        /*
         * 可執行部分
         */
        
        // 更改狀態為不可執行
        canRun = false
        
        // 等待函式執行完畢
        setTimeout(() => {
            fn(value)
            // 執行完畢後修改狀態為可執行狀態
            canRun = true
        }, wait)
    }
}
複製程式碼

看完上面的程式碼,節流是不是很像廁所檢修,檢修員進去先在門口樹一塊“不可用的”警示牌,修好之後把牌子拿走。

相關文章