防抖與節流的區別與實現

Mjser發表於2021-10-20

防抖和節流

前言

  • 作為前端開發中會以下兩種需求
    1. 搜尋需求

    搜尋的邏輯就是監聽使用者輸入事件,等使用者輸入完成之後把資料傳送給後端,後端返回匹配資料,前端顯示資料到頁面。如果只要使用者輸入就發請求,這樣會給後端造成請求壓力,需要控制請求的頻率。

    1. 頁面無限載入資料

    頁面無限載入資料的邏輯就是監聽使用者使用者滾動事件,在使用者滾動的過程中,去請求下一頁的資料來顯示到頁面。,那麼只要滾動就去發請求,同樣會造成後端請求壓力,需要控制請求的頻率。

  • 以上兩種看起來都是控制請求頻率的問題,但是需求有細微的差別:搜尋是使用者在輸入中輸入多次,只有等使用者短暫停止輸入之後,就去傳送請求,此時就需要防抖去實現。滾動載入資料是在使用者滾動頁面的過程中每間隔一段時間就去請求,即使使用者一直滾動,都會去請求,而不是等使用者停止滾動才去請求,此時就需要使用節流去實現。

防抖

  1. 含義

簡單的理解方式就是:使用者多次觸發事件,在使用者一直觸發事件中,事件不會執行,只有在使用者停止觸發事件一段時間之後再執行這個事件一次。

  1. 實現
    // @fn 是對應請求資料
    // @ms 是使用者多次觸發事件的時間間隔 是一個毫秒數
    function debounce(fn, ms) {
        let timeout = null
        return function() {
            clearTimeout(timeout)
            timeout = setTimeout(() => {
                fn.apply(this, arguments)
            }, ms)
        }
    }
  1. 原理

使用者每一次觸發事件都會延遲執行,在設定延遲定時器執之前都會把上一次延遲定時器清除,最終只有使用者連續觸發這個事件的間隔時間超出我們設定的引數ms毫秒之後,該事件才會觸發一次

  1. 測試
    <input id="searchInput"/>
    function getData(){
        console.log('傳送請求...')
    }
    document.getElementById('searchInput').oninput = debounce(getData, 800)
    // 如果使用者一直在輸入,是不會傳送請求
    // 只有使用者連續輸入時間間隔超過800ms之後才會請求一次資料,也就是使用者在800ms內沒有輸入才會去請求資料

節流

  1. 含義

簡單的理解方式就是:使用者多次觸發事件,在使用者一直觸發事件過程中事件會每間隔一段時間執行一次,會執行多次。

  1. 實現
    // @fn 是對應請求資料
    // @ms 是使用者多次觸發事件的時間間隔 是一個毫秒數
     function throttle(fn, ms){
        let flag = true
        return function(){
            if(!flag) return
            flag = false
            setTimeout(()=>{
                fn.apply(this, arguments)
                flag = true
            }, ms)
        }
    }
  1. 原理

使用者每一次觸發事件都會設定一個延遲定時器,但是如果已經設定了延遲定時器就會等上一次延遲定時器執行之後才會開啟下一個定時器,這樣使用者一直觸發事件,事件會每間隔一段時間執行一次

  1. 測試
    function getData(){
        console.log('傳送請求...')
    }
    window.onscroll = throttle(getData, 800)
    // 使用者在滾動的過程中,會間隔去請求資料

總結

節流和防抖本質上都是控制事件執行的頻率,但是觸發事件的時機本質上有區別,防抖是在使用者多次觸發事件,當使用者停止觸發事件,將事件執行一次;節流是使用者多次觸發事件,會在多次觸發的過程中,間隔執行事件。

相關文章