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

碩兒的程式設計之路發表於2017-04-17

我們都知道頻繁觸發執行一段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提示語(提示語的內容需要請求介面獲得),移出時隱藏提示語框。(提示語是當前列表項的相關內容)

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

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

實現效果圖

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

程式碼書寫

<!--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 一個不斷努力學習的女程式設計師

相關文章