微信小程序之使用函數防抖與函數節流

函數防抖和函數節流都是老生常談的問題了。這兩種方式都能優化 js 的性能。有些人可能會搞混兩個的概念。因此,我以本身的理解,來解釋這兩個概念的含義。而且列舉在小程序中這兩個方法的使用。小程序

 

函數防抖: 英文 debounce 有防反跳的意思,大體就是指防止重複觸發。閉包

那麼,函數防抖,真正的含義是:延遲函數執行即無論debounce函數觸發了多久,只在最後一次觸發debounce函數時,才定義setTimeout,到達間隔時間再執行 須要防抖的函數。函數

用處:多用於 input 框 輸入時,顯示匹配的輸入內容的狀況。性能

 

函數節流: 英文 throttle 有節流閥的意思。大體意思也是 節約觸發的頻率優化

那麼,函數節流,真正的含義是:單位時間n秒內,第一次觸發函數並執行,之後 n秒內無論觸發多少次,都不執行。直到下一個單位時間n秒,第一次觸發函數並執行,這個n秒內無論函數多少次都不執行this

用處:多用於頁面scroll滾動,或者窗口resize,或者防止按鈕重複點擊等狀況spa

 

其實若是隻根據 控制函數觸發的頻率是很差區分這兩個概念的。我認爲兩個函數都能達到防止重複觸發的功能。可是函數防抖n秒後延遲執行;而函數節流立馬執行,n秒後再立馬執行。code

 

在小程序中,函數防抖、函數節流的使用方式:blog

通常都會把這兩種方法封裝在公用的 js 中:input

tool.js

/*函數節流*/
function throttle(fn, interval) {
  var enterTime = 0;//觸發的時間
  var gapTime = interval || 300 ;//間隔時間,若是interval不傳,則默認300ms
  return function() {
    var context = this;
    var backTime = new Date();//第一次函數return即觸發的時間
    if (backTime - enterTime > gapTime) {
      fn.call(context,arguments);
      enterTime = backTime;//賦值給第一次觸發的時間,這樣就保存了第二次觸發的時間
    }
  };
}

/*函數防抖*/
function debounce(fn, interval) {
  var timer;
  var gapTime = interval || 1000;//間隔時間,若是interval不傳,則默認1000ms
  return function() {
    clearTimeout(timer);
    var context = this;
    var args = arguments;//保存此處的arguments,由於setTimeout是全局的,arguments不是防抖函數須要的。
    timer = setTimeout(function() {
      fn.call(context,args);
    }, gapTime);
  };
}

export default {
  throttle,
  debounce
};

 使用:

import tool from "../../static/js/tool.js";
Page({
   data:{
    win_scrollTop:0
   },
   onPageScroll: tool.throttle(function(msg){
      this.setData({
        win_scrollTop: msg[0].scrollTop
      });
   }),
   gotoUnlock: tool.debounce(function() {
      this.saveUserInfo();
   }),
   saveUserInfo:function(){
      console.log(111)
   }
})

 

上面的兩種方式只是精簡版的,可能還有某些狀況沒考慮到,之後遇到了再優化。

 

函數節流的說明:

(1) 第一次執行時,是必定能執行函數的。

(2) 而後 n秒內第二次觸發的時候,當第一次與第二次間隔不足 設置的間隔時間時,就不會執行。以後第3、第四次觸發仍是不執行。

(3) 直到 n秒以後 有且僅有一次,而且是第一次再次觸發函數。

 

函數防抖的說明:

(1) 第一次觸發函數時,定義了一個定時器。在 n秒後執行。

(2) 而後 函數第二次觸發的時候,因爲閉包的特性,這時候的 timer已是第一次觸發時的 定時器的標識了。而後直接清除第一次的setTimeout,這時候第一次的setTimeout裏面的內容就不會執行了。而後再定義第二次的setTimeout。

(3) 而後重複第二個步驟,一直清除,又一直設置。直到函數最後一次觸發,定義了最後的一個定時器,而且間隔 n秒 執行。

(4) 若是在 最後一個定時器沒執行時,函數又觸發了,那麼又重複第三步。至關於 設置的間隔時間,只是延遲函數執行的時間,而不是間隔多少秒再執行。

 

到這裏,這兩個方式的區別就很明顯了。函數節流減小函數的觸發頻率,而函數防抖則是延遲函數執行,而且無論觸發多少次都只執行最後一次

相關文章
相關標籤/搜索