JavaScript 中函數節流和函數去抖的講解

gu086001 7年前發布 | 17K 次閱讀 JavaScript開發 JavaScript

我們都知道頻繁觸發執行一段js邏輯代碼對性能會有很大的影響,尤其是在做一些效果實現方面,或者邏輯中需要進行后端請求,更是會導致卡頓,效果失效等結果,所以在處理類似的情況時,可以考慮使用函數節流和函數去抖來解決,至于具體使用哪一種方式,根據實際情況分析定奪,先來講解一些這兩者的概念

函數節流:在頻繁觸發的情況下,需要執行的邏輯只有執行完之后,才能繼續執行下一次

函數防抖:在頻繁觸發的情況下,只有足夠的空閑時間,才執行代碼一次,如果沒有執行完就清除掉,重新執行邏輯

應用場景:高頻觸發以下方法

  • 頁面滾動監聽(onscroll)
  • 窗口resize事件,等到窗口變化結束后才進行業務邏輯的運行
  • 鼠標鍵盤 mousedown/keydown 事件
  • 鼠標的進入移出事件(mouseenter/mouseleave)
  • DOM 元素的拖拽功能實現(mousemove)
  • 輸入框搜索等(keyup)

函數節流和函數防抖兩個概念是有很大區別的,我們用一段代碼示例來看看其究竟

// 函數節流例子
var can = true;
window.onscroll = function(){
  if(!can){
   //判斷上次邏輯是否執行完畢,如果在執行中,則直接return
   return;
  }
  can = false;
  setTimeout(function(){
    //執行邏輯
    can = true;
  }, 100);
};

可以看出上一次的邏輯必須執行完畢之后,才會執行下一次的邏輯,如果我們不做函數節流,因為滾動是一個頻繁的操作,會被時時刻刻監聽到,執行多次邏輯的觸發,做了節流會在一定程度上控制邏輯的觸發

// 函數防抖
var timer = null;
window.onscroll = function(){
    if (timer) {
      // 清除未執行的邏輯,重新執行下一次邏輯,不論上一次是否執行完畢
      clearTimeout(timer); 
    }
    timer = setTimeout(function(){
        //執行邏輯
    }, 300);
};

在函數防抖這個例子中,可以看出當事件被監控觸發時候,不論上一次的邏輯有沒有執行完畢,都要清除掉重新執行,函數防抖會更加降低事件被觸發的頻率。

真實使用案例講解:在一個列表頁面,當鼠標進入到列表中某一項時顯示一段tip提示語(提示語的內容需要請求接口獲得),移出時隱藏提示語框。(提示語是當前列表項的相關內容)

圖示:這樣一整個列表,當我們鼠標放到訂正情況上時候需要顯示訂正情況的詳細信息,而有時我們鼠標滑過的時候可能把每一條的邏輯都觸發,但是這并不是我們想要的,我們只想最后鼠標留在哪條數據上,才顯示哪一段數據的邏輯,所以根據情況的分析,我們這種情況適用的是 函數去抖

實現效果圖

代碼書寫

<!--html 一段mvvm框架的dom書寫-->
<td  ms-mouseenter="toggleItem(true,item)" ms-mouseleave="toggleItem(false,item)">
    <span>{{item.info}}</span>
    <div ms-class="show:item.isVisible">
        <p>item需要顯示的內容</p> 
    </div>
</td>
var event = null,
toggleItem:function (state,item) {
    if (state==true) {
        if (event) {
            clearTimeout(event);
        }
        event =setTimeout(function () {
            //執行item的請求顯示內容邏輯
        },100);
    }
    item.isVisible = state;
},

寫在最后的總結

所以最重要的事情就是要首先清楚地區分二者的概念,理解實現的方法,再根據具體的需求來判斷適用哪一種方法來進行優化,二者在功能實現上是有本質區別的。

Cayley 一個不斷努力學習的女程序員

 

來自:https://juejin.im/post/58f46e8944d904006c026952

 

 本文由用戶 gu086001 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!