前端函數防抖和節流

防抖:觸發事件後在n秒內函數只執行一次,若在n秒內再次觸發則重新計算下次函數響應時間

節流:連續發生的事件在n秒內只執行一次

使用場景:即時查詢等需要短時間內請求到服務器端的數據,以一定時間間隔調用函數的場景

代碼展示

  下面以鼠標的onmousemove事件來展示防抖的非立即執行和立即執行版,節流的定時器和時間戳版。

準備代碼

<div id="content"
        style="height: 150px;line-height: 150px;text-align: center;background-color: aquamarine;font-size: 30px;color: brown;">
</div>
<script>
        let num = 1;
        let content = document.getElementById('content');

        function count() {
            content.innerHTML = num++;
        }
</script>

  此時界面上有一個盒子,在盒子內可以滑動鼠標。

無防抖和節流版:鼠標一動,界面上展示的數字就加1,一動就加1

// 鼠標一經過就執行函數
content.onmousemove = count

防抖的非立即執行版:讓鼠標移動完畢後過1秒在查詢

function debounce(func, wait){
    let timeout;   // 定時器
    return function() {
        if(timeout) clearTimeout(timeout);
        timeout = setTimeout(function(){
            func.apply(this);   // 執行func函數
        }, wait)
    }
}
content.onmousemove = debounce(count, 1000)

防抖的立即執行版:讓鼠標移動完畢立即查詢,過1秒才能在查詢

function debounce(func, wait){
    let timeout;
    return function(){
        if(timeout) clearTimeout(timeout);  // 取消之前的任務
        let callNow = !timeout;   // 類型轉化
        timeout = setTimeout(() => {   // 增加一個定時器
            timeout = null       // 清空當前定時器句柄
        }, wait)
        if(callNow) func.apply(this)   // 第一次執行
    }
}
content.onmousemove = debounce(count, 1000)

節流的定時器版:啓用定時器,固定的時間去發請求

function throttle(func, wait){
   let timeout;   // 定義一個定時器句柄
    return function(){
        if(!timeout){  // 是否存在定時器
            timeout = setTimeout(() => {  // 創建一個定時器
                timeout = null;
                func.apply(this)   // apply調用函數func即count
            }, wait)
        }
    }
}
content.onmousemove = throttle(count, 1000)

節流的時間戳版:當前時間減去上次請求的時間,固定的時間去發請求

function throttle(func, wait) {
   let prev = 0;  // 上次記錄的事件
    return function () {
        let now = Date.now()   // 當前時間
        if (now - prev > wait) {  // 當前時間 - 上次時間 > 等待時間
            func.apply(this)  // 執行函數 發送請求
            prev = now  // 重置上次記錄時間
        }
    }
}
content.onmousemove = throttle(count, 1000)

總結:通過防抖和節流,在持續觸發事件的過程中可以很好的控制與後臺服務交互的次數,減少服務器端的壓力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章