函數(shù)防抖和函數(shù)節(jié)流

繼續(xù)學(xué)習(xí)的一天

前言

  • 遇見的場(chǎng)景
    最近有頻繁遇見的一個(gè)場(chǎng)景:在做搜索(包括數(shù)據(jù)量大做模糊搜索,后端實(shí)現(xiàn))時(shí),會(huì)遇見這種情況,在input標(biāo)簽上綁定@input 函數(shù)(請(qǐng)求函數(shù)),由于@input監(jiān)控變化時(shí),發(fā)請(qǐng)求非常高頻,以至于當(dāng)某一次請(qǐng)求回來的數(shù)據(jù)量非常大時(shí),在這次請(qǐng)求之后的返回?cái)?shù)據(jù)量小,所以先請(qǐng)求的數(shù)據(jù)量大的最后返回并展示在頁面上,導(dǎo)致用戶看起來頁面查詢出來的結(jié)果不正確;

    我們的目的是為了在搜索時(shí)做到結(jié)果實(shí)時(shí)顯示,但是由于@input的監(jiān) 控,在輸入搜索關(guān)鍵字的時(shí)候,發(fā)送多次http異步請(qǐng)求,這樣頻繁地請(qǐng)求會(huì)導(dǎo)致流量損耗與性能下降。

  • 類似的常見場(chǎng)景
    由于事件頻繁被觸發(fā),因而頻繁執(zhí)行DOM操作、資源加載等重行為,導(dǎo)致UI停頓甚至瀏覽器崩潰的常見場(chǎng)景:
    1、window對(duì)象的resize、scroll事件;
    2、 拖拽時(shí)的mousemove事件;
    3、文字輸入、自動(dòng)完成的keyup事件;
    為了能使這些場(chǎng)景得到優(yōu)化,就需要用到函數(shù)節(jié)流和函數(shù)防抖;

函數(shù)防抖(debounce)
  • 概念:
    當(dāng)調(diào)用動(dòng)作過n毫秒后,才會(huì)執(zhí)行該動(dòng)作,若在這n毫秒內(nèi)又調(diào)用此動(dòng)作則將重新計(jì)算執(zhí)行時(shí)間;

  • 函數(shù)實(shí)現(xiàn):

function _debounce(fn,wait){
    var timer = null;
    return function(){
        clearTimeout(timer)
        timer = setTimeout(()=>{
            fn()
        },wait)
    }
}

function fn(){
    console.log(1)
}
window.onscroll = _debounce(fn,500)

函數(shù)節(jié)流(throttle)
  • 概念:
    預(yù)先設(shè)定一個(gè)執(zhí)行周期,當(dāng)調(diào)用動(dòng)作的時(shí)刻大于等于執(zhí)行周期則執(zhí)行該動(dòng)作,然后進(jìn)入下一個(gè)新周期;

  • 函數(shù)實(shí)現(xiàn):

以頁面的滾動(dòng)事件為例,如果頁面很長(zhǎng),我們一直在滾動(dòng)頁面,那fn方法就一直不會(huì)被執(zhí)行,按照這個(gè)思路改進(jìn)一下防抖函數(shù);

function _throttle(fn,wait,time){
    var previous = null; //記錄上一次運(yùn)行的時(shí)間
    var timer = null;

    return function(){
        var now = +new Date();

        if(!previous) previous = now;
        //當(dāng)上一次執(zhí)行的時(shí)間與當(dāng)前的時(shí)間差大于設(shè)置的執(zhí)行間隔時(shí)長(zhǎng)的話,就主動(dòng)執(zhí)行一次
        if(now - previous > time){
            clearTimeout(timer);
            fn();
            previous = now;// 執(zhí)行函數(shù)后,馬上記錄當(dāng)前時(shí)間
        }else{
            clearTimeout(timer);
            timer = setTimeout(function(){
                fn();
            },wait);
        }
    }
}
function fn(){
    console.log(1)
}
window.onscroll = _throttle(fn,500,2000)

gitHub地址: https://github.com/DevilLittle/throttle

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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