溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JS函數(shù)防抖和函數(shù)節(jié)流的示例分析

發(fā)布時(shí)間:2021-05-17 14:56:54 來源:億速云 閱讀:133 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹JS函數(shù)防抖和函數(shù)節(jié)流的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

概述

函數(shù)防抖和函數(shù)節(jié)流都是定義一個(gè)函數(shù),該函數(shù)接收一個(gè)函數(shù)作為參數(shù),并返回一個(gè)添加了防抖或節(jié)流功能后的函數(shù)。

因此可以將函數(shù)防抖和函數(shù)節(jié)流看作是一個(gè)函數(shù)工廠,負(fù)責(zé)對傳進(jìn)來的函數(shù)進(jìn)行相應(yīng)的加工改造,然后產(chǎn)出一個(gè)新的帶有某種功能的函數(shù)。

函數(shù)防抖是某一時(shí)間內(nèi)只執(zhí)行一次,而函數(shù)節(jié)流是間隔時(shí)間執(zhí)行

假如有這樣一個(gè)場景:在某一頁面,有一個(gè)按鈕是 "加載更多",這個(gè)按鈕的作用就是使用 ajax 從后端服務(wù)器請求更多的數(shù)據(jù)展示在頁面,我們都知道,ajax 請求的響應(yīng)是一個(gè)異步的,會存在一定的響應(yīng)時(shí)間,如果用戶在點(diǎn)擊了該按鈕后,立馬又點(diǎn)擊了一下該按鈕,按照常規(guī)回調(diào)函數(shù)的操作,回調(diào)函數(shù)會立馬又執(zhí)行一次,那么就是用戶短時(shí)間內(nèi)點(diǎn)擊了兩次 "加載更多" 按鈕后就會執(zhí)行回調(diào)函數(shù)向后端發(fā)起了兩次一模一樣的 ajax 請求,服務(wù)器會一一接收請求并處理返回?cái)?shù)據(jù),短時(shí)間內(nèi)兩次請求還好,如果用戶連續(xù)點(diǎn)擊了 n 次 "加載更多" 按鈕呢?那就會短時(shí)間內(nèi)向服務(wù)器發(fā)送了 n 次一模一樣的請求,每次后端處理 ajax 請求后返回?cái)?shù)據(jù)后頁面就會重新再渲染一次,盡管內(nèi)容沒有改變,這樣就會帶來性能上的問題,不僅為服務(wù)器帶去了壓力,也為瀏覽器帶來了不必要的渲染,這就是函數(shù)頻繁執(zhí)行帶來的副作用。

那么如何設(shè)置這個(gè)按鈕的點(diǎn)擊事件回調(diào)函數(shù)才能減少該函數(shù)頻繁執(zhí)行帶來的副作用呢?

1. 函數(shù)防抖(debounce)

函數(shù)防抖的設(shè)計(jì)思路就是在函數(shù)執(zhí)行前加一個(gè)等待時(shí)間,在這個(gè)等待時(shí)間內(nèi)如果該函數(shù)又需要執(zhí)行一次,就重新計(jì)算等待時(shí)間,再次等待,依次類推,直到等待時(shí)間到了,還沒有等到函數(shù)又需要執(zhí)行的情況,才會執(zhí)行這個(gè)函數(shù)。

就拿上述的場景來說,假設(shè)向后臺發(fā)送 ajax 請求的響應(yīng)時(shí)間大概是在 2s 左右,那就設(shè)置這個(gè)等待時(shí)間為 2s,當(dāng)用戶第一次點(diǎn)擊"加載更多"按鈕后,該回調(diào)函數(shù)并沒有立即執(zhí)行,也就是還沒有開始發(fā)送 ajax,此時(shí)該函數(shù)在等待,如果在 2s 內(nèi)用戶又點(diǎn)擊了"加載更多",那就重新計(jì)算等待時(shí)間,再等待 2s ,此時(shí) 2s 過去了,用戶沒再第三次點(diǎn)擊"加載更多"按鈕了,那么該函數(shù)就開始執(zhí)行了,向后端發(fā)送 ajax 請求了。

函數(shù)防抖實(shí)現(xiàn)方式如下:

function debounce(fn, delay){
    let timeId = null
    return function(){
        let context = this
        if(timeId){window.clearTimeout(timeId)}
        timeId = setTimeout(()=>{
            fn.apply(context, arguments)
            timeId = null
        },delay)
    }
}

2. 函數(shù)節(jié)流(throttle)

函數(shù)節(jié)流的設(shè)計(jì)思路是在函數(shù)執(zhí)行后加一個(gè)冷卻時(shí)間,函數(shù)在第一次執(zhí)行時(shí)是立馬執(zhí)行,但在其執(zhí)行完后設(shè)置一個(gè)冷卻時(shí)間,在冷卻時(shí)間內(nèi),該函數(shù)不能再次執(zhí)行,直到冷卻時(shí)間結(jié)束允許該函數(shù)執(zhí)行了,才可以再次執(zhí)行。

就拿上述的場景來說,冷卻時(shí)間假設(shè)也設(shè)置為 2s,在用戶第一次點(diǎn)擊"加載更多" 后按鈕的回調(diào)函數(shù)就會執(zhí)行,也就是會向后臺發(fā)送 ajax 請求,此時(shí)用戶又立馬再次點(diǎn)擊了"加載更多"按鈕,由于此刻 2s 的冷卻時(shí)間還沒有到,那么就會給第二次的函數(shù)執(zhí)行加上一個(gè)延遲執(zhí)行。

function throttle(fn, delay){
    let canUse = true
    return function(){
        if(canUse){
            fn.apply(this, arguments)
            canUse = false
            setTimeout(()=>canUse=true, delay)
        }
    }
}

JavaScript有什么特點(diǎn)

1、js屬于一種解釋性腳本語言;2、在絕大多數(shù)瀏覽器的支持下,js可以在多種平臺下運(yùn)行,擁有著跨平臺特性;3、js屬于一種弱類型腳本語言,對使用的數(shù)據(jù)類型未做出嚴(yán)格的要求,能夠進(jìn)行類型轉(zhuǎn)換,簡單又容易上手;4、js語言安全性高,只能通過瀏覽器實(shí)現(xiàn)信息瀏覽或動(dòng)態(tài)交互,從而有效地防止數(shù)據(jù)的丟失;5、基于對象的腳本語言,js不僅可以創(chuàng)建對象,也能使用現(xiàn)有的對象。

以上是“JS函數(shù)防抖和函數(shù)節(jié)流的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI