淺聊防抖與節流 實現與應用

   '' 前端

防抖與節流

導讀目錄
node

  • 防抖(debounce)git

    • 防抖應用場景github

    • 非當即執行版web

    • 當即執行版本瀏覽器

    • 合成版本 防抖服務器

  • 節流微信

    • 節流應用場景app

    • 時間戳版本編輯器

    • 定時器版本

  • 總結

    • 參考


1防抖(debounce)

所謂防抖,就是指觸發事件後 n 秒後才執行函數,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。

防抖類型分爲

  1. 非當即執行版
  2. 當即執行版
  3. 合成版本 防抖

防抖應用場景

  • 登陸、發短信等按鈕避免用戶點擊太快,以至於發送了屢次請求
  • 調整瀏覽器窗口大小時,resize 次數過於頻繁,形成計算過多,此時須要一次到位
  • 文本編輯器實時保存,當無任何更改操做一秒後進行保存

非當即執行版

非當即執行版的意思是觸發事件後函數不會當即執行,而是在 n 秒後執行,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。

/**
 * @description
 * @param {*} func 觸發的時間
 * @param {*} wait 多少時長才執行事件
 * @return {*}
 */

        function debounce(func, wait{
            let timeout;
            return function(){
                // 獲取當前做用域和參數
                const context = this;
                const args = [...arguments] 
                // 若是當前timeout 存在
                // 清空定時器,再次等待wait時間事後再次執行事件
                if(timeout) clearTimeout(timeout)
                // 定時執行 傳遞進來的事件
                timeout = setTimeout(()=>{
                    func.apply(context,args)
                },wait)  
            }
        }

當即執行版本

當即執行版的意思是觸發事件後函數會當即執行,而後 n 秒內不觸發事件才能繼續執行函數的效果。

function debounce(func,wait{
  let timeout;
  return function ({
      const context = this;
      const args = [...arguments];
      if (timeout) clearTimeout(timeout);
      const callNow = !timeout;
      timeout = setTimeout(() => {
          timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
  }
}

代碼解析

當 執行 debounce 函數時, 第一次進來時,timeout 爲false,因此 callNow 的值 爲 true ,那麼它會當即執行 func 函數,這時 timeout 的值 爲 true , 當 timeout 值爲true 時, 會執行 清空定時器,此時 timeout 又爲 false 了 , 這時 callNow  又 爲 true ,再次執行 func 函數。

一直循環這樣的操做:

timeoutfalse 時,會馬上執行 func 函數。

timeouttrue 時,它會執行clearTimeOut ,這時timeout 又爲 false,  而 callNow  = ! timeout , 就會馬上執行 func 函數了。

合成版本 防抖

經過傳遞 Boolean 來決定執行哪一種版本。

  • true 爲當即執行版
  • false 爲非當即執行版本

debounce(func,1000,true)

/**
 * @desc 函數防抖
 * @param func 函數
 * @param wait 延遲執行毫秒數
 * @param immediate true 表當即執行,false 表非當即執行
 */

function debounce(func, wait, immediate{
  let timeout;
  return function ({
    const context = this;
    const args = [...arguments];
    if (timeout) clearTimeout(timeout);
    if (immediate) {
      const callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
    }
    else {
      timeout = setTimeout(() => {
        func.apply(context, args)
      }, wait);
    }
  }
}

2節流

所謂節流,就是指連續觸發事件可是在 n 秒中只執行一次函數。 節流會稀釋函數的執行頻率。

節流有兩種實現:

  1. 時間戳版本
  2. 定時器版本

節流應用場景

  1. scroll 事件,每隔一秒計算一次位置信息等
  2. 瀏覽器播放事件,每一個一秒計算一次進度信息等
  3. input 輸入框在搜索內容時,能夠控制多少s 在執行請求,避免屢次發起請求,節約性能。

時間戳版本

function throttle(func, wait{
    var previous = 0;
    return function({
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

定時器版本

function throttle(func, wait{
    let timeout;
    return function({
        let context = this;
        let args = arguments;
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }

    }
}

代碼解析

當執行 throttle 函數時,timeout 默認爲undefined , 此時,! timeouttrue 時,執行 定時器,而且 將 timeout 爲 null,即爲false, 再次執行throttle 函數時,!timeout 又爲 true ,再次執行定時器。

**經過 timeout  的狀態來達到節流的控制 **

3總結

  • 防抖:觸發事件後,必定時間後再執行事件,能夠當即執行 也能夠必定時間再執行

  • 節流:控制流量,在單位時間內只能請求一次,避免屢次觸發事件,影響服務器性能。

參考

https://github.com/mqyqingfeng/Blog/issues/26



React Hook |    9  

Vue

Vue  8 

MYSQL

TypeScript(PDF+)








本文分享自微信公衆號 - 前端自學社區(gh_ce69e7dba7b5)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索