中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行javascript的防抖節流函數解析

發布時間:2022-01-15 14:44:22 來源:億速云 閱讀:333 作者:柒染 欄目:開發技術

這期內容當中小編將會給大家帶來有關如何進行javascript的防抖節流函數解析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

防抖節流函數的解析

認識防抖和節流函數

防抖和節流的概念其實最早并不是出現在軟件工程中,防抖是出現在電子元件中,節流出現在流體流動中

  • 而JavaScript是事件驅動的,大量的操作會觸發事件,加入到事件隊列中處理。

  • 而對于某些頻繁的事件處理會造成性能的損耗,我們就可以通過防抖和節流來限制事件頻繁的發生;

防抖和節流函數目前已經是前端實際開發中兩個非常重要的函數,也是面試經常被問到的面試題

但是很多前端開發者面對這兩個功能,有點摸不著頭腦:

  • 某些開發者根本無法區分防抖和節流有什么區別(面試經常會被問到);

  • 某些開發者可以區分,但是不知道如何應用;

  • 某些開發者會通過一些第三方庫來使用,但是不知道內部原理,更不會編寫;

認識防抖debounce函數

我們用一副圖來理解一下它的過程:

  • 當事件觸發時,相應的函數并不會立即觸發,而是會等待一定的時間;

  • 當事件密集觸發時,函數的觸發會被頻繁的推遲;

  • 只有等待了一段時間也沒有事件觸發,才會真正的執行響應函數;

如何進行javascript的防抖節流函數解析

防抖的應用場景很多:

  • 輸入框中頻繁的輸入內容,搜索或者提交信息;

  • 頻繁的點擊按鈕,觸發某個事件;

  • 監聽瀏覽器滾動事件,完成某些特定操作;

  • 用戶縮放瀏覽器的resize事件;

防抖函數的案例

我們都遇到過這樣的場景,在某個搜索框中輸入自己想要搜索的內容

比如想要搜索一個MacBook:

  • 當我輸入m時,為了更好的用戶體驗,通常會出現對應的聯想內容,這些聯想內容通常是保存在服務器的,所以需要一次網絡請求;

  • 當繼續輸入ma時,再次發送網絡請求;

  • 那么macbook一共需要發送7次網絡請求;

  • 這大大損耗我們整個系統的性能,無論是前端的事件處理,還是對于服務器的壓力;

但是我們需要這么多次的網絡請求嗎?

  • 不需要,正確的做法應該是在合適的情況下再發送網絡請求;

  • 比如如果用戶快速的輸入一個macbook,那么只是發送一次網絡請求;

  • 比如如果用戶是輸入一個m想了一會兒,這個時候m確實應該發送一次網絡請求;

  • 也就是我們應該監聽用戶在某個時間,比如500ms內,沒有再次觸發時間時,再發送網絡請求;

這就是防抖的操作:只有在某個時間內,沒有再次觸發某個函數時,才真正的調用這個函數;

認識節流throttle函數

我們用一副圖來理解一下節流的過程

  • 當事件觸發時,會執行這個事件的響應函數;

  • 如果這個事件會被頻繁觸發,那么節流函數會按照一定的頻率來執行函數;

  • 不管在這個中間有多少次觸發這個事件,執行函數的頻繁總是固定的;

如何進行javascript的防抖節流函數解析

節流的應用場景:

  • 監聽頁面的滾動事件;

  • 鼠標移動事件;

  • 用戶頻繁點擊按鈕操作;

  • 游戲中的一些設計;

節流函數的應用場景

很多人都玩過類似于飛機大戰的游戲

在飛機大戰的游戲中,我們按下空格會發射一個子彈:

  • 很多飛機大戰的游戲中會有這樣的設定,即使按下的頻率非常快,子彈也會保持一定的頻率來發射;

  • 比如1秒鐘只能發射一次,即使用戶在這1秒鐘按下了10次,子彈會保持發射一顆的頻率來發射;

  • 但是事件是觸發了10次的,響應的函數只觸發了一次;

如何進行javascript的防抖節流函數解析

自定義防抖和節流函數

我們按照如下思路來實現:

防抖基本功能實現:可以實現防抖效果

  • 優化一:優化參數和this指向

  • 優化二:優化取消操作(增加取消功能)

  • 優化三:優化立即執行效果(第一次立即執行)

  • 優化四:優化返回值

function debounce(fn,delay,immediate=false,resultCallback){
  let timer=null
  // console.log(this)//window
  // 定義控制立即執行的變量,false表示沒有執行過
  let isInvoke=false
  // 真正的處理函數
  function _debounce(...args){
    // 取消事件執行操作
    if(timer) clearTimeout(timer)
    // console.log(this)//element元素
    if(immediate&&!isInvoke){
      const result=fn.apply(this,args)
      resultCallback(result)
      isInvoke=true
    }else{
      // 延遲執行
      timer=setTimeout(()=>{
        const result=fn.apply(this,args)
        resultCallback(result)
        timer=null
        isInvoke=false
      },delay)
    }
  }
  // 封裝取消請求
  _debounce.cancel=function(){
    if(timer) clearTimeout(timer)
    timer=null
    isInvoke=false
  }
  return _debounce
}

我們按照如下思路來實現:

節流函數的基本實現:可以實現節流效果

  • 優化一:節流最后一次也可以執行

  • 優化二:優化添加取消功能

  • 優化三:優化返回值問題

function throttle(fn,interval,options={leading:true,trailing:false}){
  let lastTime=0
  const {leading,trailing,resultCallback}=options
  let timer=null
  function _throttle(...args){
    const nowTime=new Date().getTime()
    // leading優化
    if(!leading&&!lastTime) lastTime=nowTime
    let remainTime=interval-(nowTime-lastTime)
    if(remainTime<=0){
      if(timer){
        clearTimeout(timer)
        timer=null
      }
      // 參數優化
      const result=fn.apply(this,args)
      if(resultCallback) resultCallback(result)
      lastTime=nowTime
      return
    } 
    // 優化trailing
    if(!timer&&trailing){
      timer=setTimeout(()=>{
        // 參數優化
        const result=fn.apply(this,args)
        if(resultCallback) resultCallback(result)
        timer=null
        lastTime=!leading?0:new Date().getTime()
      },remainTime)
    }
  }
  _throttle.cancel=function(){
    if(timer) clearTimeout(timer)
    timer = null
    lastTime = 0
  }
  return _throttle
}

上述就是小編為大家分享的如何進行javascript的防抖節流函數解析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

舟曲县| 竹溪县| 深州市| 班玛县| 瑞金市| 洛川县| 四会市| 屏东县| 金湖县| 静宁县| 班玛县| 张掖市| 介休市| 东光县| 屏南县| 会理县| 巴青县| 烟台市| 浙江省| 丁青县| 伊川县| 鸡西市| 武功县| 双牌县| 石台县| 扶风县| 西畴县| 霍山县| 黎平县| 庆安县| 南城县| 沾益县| 永靖县| 康保县| 平度市| 安化县| 曲松县| 丹凤县| 鄯善县| 文昌市| 黄梅县|