函數防抖與函數節流原理及使用

前言

在類似scroll、resize事件中執行大量DOM操作或者計算時,就會出現再次觸發事件而上一次事件中的DOM操作和計算還沒完成的情況,結果瀏覽器掉幀了,導致性能下降,影響用戶體驗。而函數節流和函數防抖,兩者都是優化高頻率執行js代碼的一種手段。因此,可以用以下兩種方式優化代碼。

概念

一、函數防抖:
指頻繁觸發的情況下,只有足夠的空閑時間,才執行代碼一次,也就是讓某個函數在上一次執行后, 滿足等待某個時間內不再觸發此函數后再執行, 而在這個等待時間內再次觸發此函數, 等待時間會重新計算.實際需求多數為停止操作n毫秒后執行后續處理 。
二、函數節流:
指為這個操作(函數)預先設定一個執行周期,當調用動作的時刻>=執行周期則執行該動作,然后進入下一個新周期,否則不執行。簡單來說就是你的js方法在一定時間內只跑一次(頻率)。

適用場景

一、函數節流:
場景一:頁面元素滾動的時候,觸發某個事件。
場景二:高頻率點擊表單提交按鈕,表單重復提交。

實現要點:聲明一個變量當標志位,記錄當前代碼是否在執行,
var valve = true;   //標志位
document.getElementById("box").onscroll = function(){
// 判斷是否已空閑,如果在執行中,則直接return,如果空閑,則可以正常觸發方法執行。
 if(!valve){
    return;  
 }
 valve = false; //關閉
//要執行的函數
    something()
};
function something(){
  setTimeout(function(){
  console.log("函數節流");
  valve = true;//執行周期完成后打開閥門,允許再次調用
  }, 300);
}

二、函數防抖:
場景一:表單驗證,用戶停止輸入后,然后開啟驗證
場景二:輪播圖等

實現要點:巧用setTimeout做緩存池,可以輕易地清除待執行的代碼。
// 函數防抖
var timer = false;
document.getElementById("box").onscroll = function(){
    clearTimeout(timer); // 清除未執行的代碼,重置回初始化狀態
    timer = setTimeout(function(){
     //滾動事件停止300毫秒后 調用
        console.log("函數防抖");
    }, 300);
};  

案例

一(防抖)、假設網站有個搜索框, 用戶輸入文本我們會自動聯想匹配出一些結果供用戶選擇,我們可能首先想到的做法就是監聽keypress事件, 然后異步查詢結果. 但是如果用戶快速的輸入了一串字符, 假設是10個字符, 那么就會在瞬間觸發10次請求, 這無疑不是我們想要的, 我們想要的是用戶停止輸入的時候才去觸發查詢的請求.
二(防抖vs節流)
假設網站有登錄框, 用戶登錄信息后,自動驗證用戶信息,首先監聽輸入框oninput事件, 然后異步驗證登錄信息.驗證成功點擊登錄按鈕,進行登錄操作。 但是這樣的話用戶每輸入了個字符, 就會調用一次oninput事件,那么就觸發1次請求, 這無疑不是我們想要的, 我們想要的是用戶停止輸入的時候才去觸發驗證的請求.(##這里可以用函數防抖處理 ,幾百毫秒后執行驗證信息##)
驗證成功后,進行登錄操作,調用登錄接口,但是如果高頻率點擊登錄按鈕,會不停調用登錄接口,(##這里可以用函數節流處理 ,在上次登錄接口調用完成之前,不能再次調用##)

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容