js防抖節(jié)流新姿勢

什么是防抖節(jié)流

為了防止某個特定的函數(shù)(尤其是內(nèi)部有異步操作)在未得到結(jié)果前被重復(fù)執(zhí)行,或者想要用戶輸入、頁面滾動等行為所對應(yīng)的函數(shù)不那么頻繁的被觸發(fā)而使用的限制操作稱為防抖節(jié)流。

let isPending=false;//--
async function throttle(){
    if(isPending) return;//--
    isPending=true;//--
    try{//--
        await new Promise(resolve=>{
            setTimeout(_=>{
                resolve();//或者reject
            },3000)
        })
    }catch(err){
        //do nothing
    };
    isPending=false;//--
}

但是這樣仍然比較麻煩,因?yàn)槲覀兇蟛糠智闆r下寫了一堆額外的代碼只是為了讓開關(guān)正常歸位。

不過最近在寫egg+vue+ts服務(wù)端渲染的時(shí)候使用了基于類的api開發(fā)方式,雖然感覺vuex結(jié)合ts并不太甜但是感覺ts還是真香,vue 的class寫法雖然讓我們喪失了mapState這樣非常方便的操作但同時(shí)解鎖了新的黑科技--decorator(裝飾器),下面我們使用裝飾器來實(shí)現(xiàn)一個非侵入式的節(jié)流功能;

/**
 * @param {number} deylay當(dāng)函數(shù)執(zhí)行完后再次執(zhí)行的時(shí)間間隔
 */
function Throttle(deylay: number = 0): Function {
    let isPending: boolean = false;
    return (target: any, name: string, descriptor: any) => {
        var oldValue = descriptor.value;
        //重寫函數(shù)
        descriptor.value = async function (...args: any[]) {
            if (isPending) return;
            isPending = true;
            try {
                await oldValue.apply(this, args);
            } catch (err) {
                //do nothing
            };
            if (!deylay) return isPending = false;
            setTimeout(() => {
                isPending = false;
            }, deylay);
        };
        return descriptor;
    };
};
//測試
class Test {
    @Throttle()
    public async fn():Promise<void>{
        console.log("fn 執(zhí)行了");
        await new Promise(resolve => {
            setTimeout(()=> {
                resolve();
            }, 3000);
        });
    };
};
const test = new Test();
setInterval(test.fn,50);

利用類似的思路我們同樣可以實(shí)現(xiàn)請求耗時(shí)、日志等很多功能:

//經(jīng)測試會有毫秒級的誤差
function TimeCost(target, name, descriptor) {
    var oldValue = descriptor.value;
    descriptor.value = async function (...args) {
        const timeStart = new Date().getTime()
        try {
            await oldValue.apply(this, args);
        } catch (err) {
          //
        };
        console.log(`function:[${name}] costs: ${new Date().getTime() - timeStart}ms`);
    };
    return descriptor;
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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