JavaScript:函數防抖與函數節流

防抖(debounce)

名詞解釋:在事件被觸發n秒後再執行回調函數,如果在這n秒內又被觸發,則重新計時。

使用場景:以百度輸入框例,比如你要查詢XXx,想實現輸完了XXx之後,再進行搜索請求,這樣可以有效減少請求次數,節約請求資源。

函數防抖簡單實現

<script type="text/javascript">
    window.onload = function () {            
        function ajax(content) {//模擬ajax請求
            console.log('ajax request ' + content)
        }
        function debounce(fun, delay) {
            return function (arguments) {
                //獲取函數的作用域和變量
                let that = this;
                let args = arguments;                    
                clearTimeout(fun.id)// 清除定時器
                fun.id = setTimeout(function () {
                    fun.call(that, args )
                }, delay)
            }
        }            
        let debounceAjax = debounce(ajax, 1000)
        XXX.addEventListener('keyup', function (e) {
            debounceAjax(e.target.value)
        })
    }
</script>

節流(throttle)

名詞解釋:連續執行函數,每隔一定時間執行函數。規定一個單位時間,在這個單位時間內,只能有一次觸發事件的回調函數執行,如果在同一個單位時間內某事件被觸發多次,只有一次能生效。

使用場景:鼠標連續多次click事件,mousemove 事件,監聽滾動事件,比如是否滑到底部自動加載更多等等...

函數節流簡單實現

function throttle(fn, delay) {
    let lastTime; 
    let timer; 
    delay || (delay = 300); // 默認間隔爲300ms
    return function(arguments) {
        let context = this;
        let args = arguments;
        let nowTime = +new Date(); // 獲取系統當前的時間
        if (lastTime && nowTime < lastTime+ delay) { // 當前距離上次執行的時間小於設置的時間間隔
            clearTimeout(timer); // 清除定時器
            timer = setTimeout(function() { // delay時間後,執行函數
                lastTime= nowTime ;
                fn.apply(context, args);
            }, delay);
        } else { // 當前距離上次執行的時間大於等於設置的時間,直接執行函數
            lastTime= nowTime ;
            fn.apply(context, args);
        }
    };
}

區別:

可以用日常進入電梯來舉例,形象地描述節流和防抖的區別

函數防抖:如果A在10:00:00開門走入電梯內(觸發事件),如果後續沒有人進入電梯,電梯將在5秒鐘之後10:00:05關門(執行事件監聽器)。這時如果B在10:00:04走入電梯內,電梯會在10:00:09才關門。

函數節流 :如果A在10:00:00開門走入電梯內(觸發事件),如果後續沒有人進入電梯,電梯將在5秒鐘之後10:00:05關門(執行事件監聽器)。這時如果B在10:00:04走入電梯內,電梯同樣是在10:00:05關門。這個時間從第一個人進入電梯開始計時,不管在5秒之內進來多少人,電梯都會在10:00:05關門。如果一直沒有人進來,則電梯不運行。

總結:

根據實際業務場景,合理的利用debounce(防抖)和throttle(節流)可以優化性能和提高用戶體驗。

效果:
函數防抖是某一段時間內只執行一次;
函數節流是間隔時間執行,不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數。

原理:
防抖是維護一個計時器,規定在delay時間後觸發函數,但是在delay時間內再次觸發的話,都會清除當前的 timer 重新計時。這樣一來,只有最後一次操作事件才被真正觸發。
節流是通過判斷是否到達一定時間來觸發函數,若沒到規定時間則使用計時器延後,而下一次事件則會重新設定計時器。

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