vue正確的使用函數(shù)的防抖與節(jié)流

vue中的正確使用方式

1.png

在這個地方相信好多人的使用方式,會直接定義函數(shù),然后在函數(shù)中使用debounce的 ,這樣的使用方法是錯誤的


2.png

為啥呢?這個和vue的事件綁定原理有關(guān),這里不詳細(xì)介紹。如果直接在函數(shù)體內(nèi)部使用的話,最后的結(jié)果是,一個匿名的立即執(zhí)行函數(shù)來進行執(zhí)行,這樣是不對的

原理

函數(shù)的防抖

函數(shù)的防抖是在多少時間后再來執(zhí)行函數(shù),我們可以理解為這樣的一種生活場景(坐升降電梯),
在點擊電梯的開門按鈕后,電梯會開門,然后等待一段時間來關(guān)門。但是如果在等待的期間,
有人再次點擊開門按鈕,那么電梯后繼續(xù)等待關(guān)門時間,直到等待關(guān)門時間結(jié)束,沒有人來
點擊開門按鈕后,電梯才會開始工作。

第一次非立即執(zhí)行

export function debounce(f, t){
    let timer;
    return (...arg) => {
        clearTimeout(timer);
        timer = setTimeout(() =>{
            f( ...arg)
        }, t)
    }
}
20210516221519342.gif

第一次立即執(zhí)行

對于有些場景來說,第一次我不需要等待,需要立即執(zhí)行,例如:打開控制臺獲取窗口試圖大小
(這里我們需要一直改變窗口的大小,等停下來再次獲取窗口視圖大?。?
export function debounceFirstExe(f, t){
    let timer, flag = true;
    return (...args) => {
        if (flag){
            f(...args);
            flag = false;
        }else {
            clearTimeout(timer);
            timer = setTimeout(() => {
                f(...args);
                flag = true;
            }, t)
        }
    }
}
35.gif
export  function  debounce(f, t,im = false){
    let timer, flag = true;
    return (...args) => {
        // 需要立即執(zhí)行的情況
       if (im){
           if (flag){
               f(...args);
               flag = false;
           }else {
               clearTimeout(timer);
               timer = setTimeout(() => {
                   f(...args);
                   flag = true
               }, t)
           }
       }else {
           // 非立即執(zhí)行的情況
           clearTimeout(timer);
           timer = setTimeout(() => {
               f(...args)
           }, t)
       }
    }
}
444.gif

函數(shù)防抖對于我們代碼層面我們可以用在哪里呢?

在點贊、輸入框校驗、取消點贊、創(chuàng)建訂單等發(fā)送網(wǎng)絡(luò)氫氣的時候,如果我們連續(xù)點擊按鈕,
可能會發(fā)送多次請求。這個對于后臺來說是不允許的。
在鼠標(biāo)每次 resize/scroll 觸發(fā)統(tǒng)計事件。

函數(shù)節(jié)流

與函數(shù)防抖的胞兄,函數(shù)節(jié)流的原理也是大同小異,函數(shù)節(jié)流是在一定時間內(nèi)我只會執(zhí)行一次。

第一次非立即執(zhí)行

export function throttle(f,t){
    let timer=true;
    return (...arg)=>{
        if(!timer){
            return;
        }
        timer=false;
        setTimeout(()=>{
            f(...arg);
            timer=true;
        },t)

    }
}
555.gif

在效果中,我們點擊了非常多次,但是就只執(zhí)行了4次,因為我規(guī)定的時間是1000ms執(zhí)行一次。這樣也是減少了執(zhí)行次數(shù)。

第一次立即執(zhí)行版本

export function throttleFirstExt(f, t) {
    let flag = true;
    return (...args) => {
        if (flag) {
            f(...args);
            flag = false;
            setTimeout(() => {
                flag = true
            }, t)
        }
    }
}
66.gif

這里我們看到了,第一次點擊會立馬執(zhí)行。

合并版

export function throttle(f, t, im = false){
    let flag = true;
    return (...args)=>{
        if(flag){
            flag = false
            im && f(...args)
            setTimeout(() => {
                !im && f(...args)
                flag = true
            },t)
        }
    }
}
666666.gif

應(yīng)用場景:

DOM 元素的拖拽功能實現(xiàn)(mousemove)
搜索聯(lián)想(keyup)
計算鼠標(biāo)移動的距離(mousemove)
Canvas 模擬畫板功能(mousemove)
射擊游戲的 mousedown/keydown 事件(單位時間只能發(fā)射一顆子彈)
監(jiān)聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 后,只有用戶停止
滾動后,才會判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容