淺談JavaScript節流與防抖

節流與防抖

背景:當我們頻繁去請求資源、接口等其他的時候,就會造成操作Dom頻繁,接口壓力大等等,性能下降。比如我有時候會每次搜索會猛地敲回車,在網絡不很好的時候,點擊下一頁按鈕的時候也會一直點,可能網絡不好也可能服務器性能低。

為瞭避免頻繁觸發同一事件或請求,這時候就要用到節流和防抖瞭。

what?這是啥?當我第一次聽到這兩個名字的時候,心想是指節省流量、防止手抖嗎。百思不得其解,趕緊就去學習。

概念:

簡單來說:節流和防抖就是為瞭防止事件在短時間內多次觸發的兩種解決方案。都是用過減少請求的次數,來降低壓力,提高性能。

區別

節流:在一定的時間內隻會請求一次。

可以理解為:公交車,每個人是一次點擊請求,每十分鐘開一趟車,發送請求

防抖:觸發事件後n秒後才能執行函數,如果在n秒內觸發瞭事件,則會重新計算執行時間。

比如在一段時間內,我一直點擊按鈕,以最後一次點擊為準發送一次請求。

節流實現

解決思路 :

使用時間戳(發生在一段時間的開始),就是在計算

當前點擊的時間 – 上一次執行函數的時間 > 我設定的時間戳 ,就執行一次函數

缺點:第一次直接觸發 最後一次一段時間內無法觸發

給一個場景,當我們搜索數據的時候,發起請求,沒有做處理是這樣的,請求肯定太過於頻繁

在這裡插入圖片描述

節流函數

代碼:

<body>
    <div>
        <span>節流處理</span><input id="input" type="text">
        <button id="btn">請求</button>
    </div>
</body>
<script>
    var btn = document.getElementById("btn")
    btn.addEventListener("click", throttle(output, 1000))  //添加點擊事件監聽
    function output(e) {
        console.log(this, e)
        console.log(document.getElementById("input").value)  //模擬發起一次請求
    }
//節流函數
    function throttle(fn, delay) {  // fn為執行的函數,delay為延遲時間
        var last = 0;  //上一次結束的時間
        return function () {
            var cur = Date.now()
            console.log(cur-last)
            if (cur - last > delay) {
                fn.apply(this, arguments)  //執行函數
                last = cur //更新上一次時間
            }
        }
    }
</script>

效果:

在這裡插入圖片描述

防抖實現

解決思路 :

定時器(發生在定時結束)。缺點:第一次不觸發 最後一次延遲觸發

就是設置一個定時器,如果一直點擊則清除定時器,最後一次開啟定時器

防抖函數

代碼:

<body>
    <div>
        <span>防抖處理</span><input id="input" type="text">
        <button id="btn">請求</button>
    </div>
</body>
<script>
    var btn = document.getElementById("btn")
    btn.addEventListener("click", debounce(output, 1000))  //添加點擊事件監聽
    function output(e) {
        console.log(this, e)
        console.log(document.getElementById("input").value)  //模擬發起一次請求
    }
    function debounce(fn, delay) {  // fn為執行的函數,delay為延遲時間
        var time = null;  //定時器
        return function () {
            clearTimeout(time);  //清除定時器
            let context = this;  //獲取當前button上下文 如果不指定,箭頭函數就會一直往外找到window
            let args = arguments;
            time = setTimeout(() => {
                fn.apply(context, args);
            }, delay);
        }
    }
</script>

效果:

在這裡插入圖片描述

防抖升級版

第一次觸發和最後一次延遲觸發

代碼:

    function throttle(fn, delay) {  // fn為執行的函數,delay為延遲時間
        let time = null
        let flag=true  //標識是不是第一次觸發
        return function () {
            clearTimeout(time)
            if (flag) { 
                fn.apply(this, arguments)
                flag=false
            }
            time = setTimeout(() => {  //觸發定時器
                fn.apply(this, arguments)
                flag=true
            }, delay)
        }
    }

效果:

在這裡插入圖片描述

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

節流與防抖

背景:當我們頻繁去請求資源、接口等其他的時候,就會造成操作Dom頻繁,接口壓力大等等,性能下降。比如我有時候會每次搜索會猛地敲回車,在網絡不很好的時候,點擊下一頁按鈕的時候也會一直點,可能網絡不好也可能服務器性能低。

為瞭避免頻繁觸發同一事件或請求,這時候就要用到節流和防抖瞭。

what?這是啥?當我第一次聽到這兩個名字的時候,心想是指節省流量、防止手抖嗎。百思不得其解,趕緊就去學習。

概念:

簡單來說:節流和防抖就是為瞭防止事件在短時間內多次觸發的兩種解決方案。都是用過減少請求的次數,來降低壓力,提高性能。

區別

節流:在一定的時間內隻會請求一次。

可以理解為:公交車,每個人是一次點擊請求,每十分鐘開一趟車,發送請求

防抖:觸發事件後n秒後才能執行函數,如果在n秒內觸發瞭事件,則會重新計算執行時間。

比如在一段時間內,我一直點擊按鈕,以最後一次點擊為準發送一次請求。

節流實現

解決思路 :

使用時間戳(發生在一段時間的開始),就是在計算

當前點擊的時間 – 上一次執行函數的時間 > 我設定的時間戳 ,就執行一次函數

缺點:第一次直接觸發 最後一次一段時間內無法觸發

給一個場景,當我們搜索數據的時候,發起請求,沒有做處理是這樣的,請求肯定太過於頻繁

在這裡插入圖片描述

節流函數

代碼:

<body>
    <div>
        <span>節流處理</span><input id="input" type="text">
        <button id="btn">請求</button>
    </div>
</body>
<script>
    var btn = document.getElementById("btn")
    btn.addEventListener("click", throttle(output, 1000))  //添加點擊事件監聽
    function output(e) {
        console.log(this, e)
        console.log(document.getElementById("input").value)  //模擬發起一次請求
    }
//節流函數
    function throttle(fn, delay) {  // fn為執行的函數,delay為延遲時間
        var last = 0;  //上一次結束的時間
        return function () {
            var cur = Date.now()
            console.log(cur-last)
            if (cur - last > delay) {
                fn.apply(this, arguments)  //執行函數
                last = cur //更新上一次時間
            }
        }
    }
</script>

效果:

在這裡插入圖片描述

防抖實現

解決思路 :

定時器(發生在定時結束)。缺點:第一次不觸發 最後一次延遲觸發

就是設置一個定時器,如果一直點擊則清除定時器,最後一次開啟定時器

防抖函數

代碼:

<body>
    <div>
        <span>防抖處理</span><input id="input" type="text">
        <button id="btn">請求</button>
    </div>
</body>
<script>
    var btn = document.getElementById("btn")
    btn.addEventListener("click", debounce(output, 1000))  //添加點擊事件監聽
    function output(e) {
        console.log(this, e)
        console.log(document.getElementById("input").value)  //模擬發起一次請求
    }
    function debounce(fn, delay) {  // fn為執行的函數,delay為延遲時間
        var time = null;  //定時器
        return function () {
            clearTimeout(time);  //清除定時器
            let context = this;  //獲取當前button上下文 如果不指定,箭頭函數就會一直往外找到window
            let args = arguments;
            time = setTimeout(() => {
                fn.apply(context, args);
            }, delay);
        }
    }
</script>

效果:

在這裡插入圖片描述

防抖升級版

第一次觸發和最後一次延遲觸發

代碼:

    function throttle(fn, delay) {  // fn為執行的函數,delay為延遲時間
        let time = null
        let flag=true  //標識是不是第一次觸發
        return function () {
            clearTimeout(time)
            if (flag) { 
                fn.apply(this, arguments)
                flag=false
            }
            time = setTimeout(() => {  //觸發定時器
                fn.apply(this, arguments)
                flag=true
            }, delay)
        }
    }

效果:

在這裡插入圖片描述

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: