本篇內(nèi)容從節(jié)流和去抖的概念基礎(chǔ)知識(shí)講起,對(duì)JS函數(shù)做了詳細(xì)的分析,一起來(lái)看下:
1、什么是節(jié)流和去抖?
節(jié)流。就是擰緊水龍頭讓水少流一點(diǎn),但是不是不讓水流了。想象一下在現(xiàn)實(shí)生活中有時(shí)候我們需要接一桶水,接水的同時(shí)不想一直站在那等著,可能要離開(kāi)一會(huì)去干一點(diǎn)別的事請(qǐng),讓水差不多流滿一桶水的時(shí)候再回來(lái),這個(gè)時(shí)候,不能把水龍頭開(kāi)的太大,不然還沒(méi)回來(lái)水就已經(jīng)滿了,浪費(fèi)了好多水,這時(shí)候就需要節(jié)流,讓自己回來(lái)的時(shí)候水差不多滿了。那在JS里有沒(méi)有這種情況呢,典型的場(chǎng)景是圖片懶加載監(jiān)聽(tīng)頁(yè)面的scoll事件,或者監(jiān)聽(tīng)鼠標(biāo)的mousemove事件,這些事件對(duì)應(yīng)的處理方法相當(dāng)于水,由于scroll和mousemove在鼠標(biāo)移動(dòng)的時(shí)候會(huì)被瀏覽器頻繁的觸發(fā),會(huì)導(dǎo)致對(duì)應(yīng)的事件也會(huì)被頻繁的觸發(fā)(水流的太快了),這樣就會(huì)造成很大的瀏覽器資源開(kāi)銷,而且好多中間的處理是不必要的,這樣就會(huì)造成瀏覽器卡頓的現(xiàn)象,這時(shí)候就需要節(jié)流,如何節(jié)流呢?我們無(wú)法做到讓瀏覽器不去觸發(fā)對(duì)應(yīng)的事件,但是可以做到讓處理事件的方法執(zhí)行頻率減少,從而減少對(duì)應(yīng)的處理開(kāi)銷。
去抖。最早接觸這個(gè)詞應(yīng)該是在高中物理里面學(xué)到的,有時(shí)候開(kāi)關(guān)在在真正閉合之前可能會(huì)發(fā)生一些抖動(dòng)現(xiàn)象,如果抖動(dòng)的明顯的話,對(duì)應(yīng)的小燈泡可能會(huì)閃爍,把燈泡閃壞了不重要,萬(wàn)一把眼睛再給閃壞了可就麻煩了,這個(gè)時(shí)候就有去抖電路的出現(xiàn)。而在我們的頁(yè)面里,也有這種情況,假設(shè)我們的一個(gè)輸入框,輸入內(nèi)容的同時(shí)可能會(huì)去后臺(tái)查詢對(duì)應(yīng)的聯(lián)想 詞,如果用戶輸入的同時(shí),頻繁的觸發(fā)input事件,然后頻繁的向后抬發(fā)送請(qǐng),那么直到用戶輸入完成時(shí),之前的請(qǐng)求都應(yīng)該是多余的,假設(shè)網(wǎng)絡(luò)慢一點(diǎn),后臺(tái)返回的數(shù)據(jù)比較慢,那么顯示的聯(lián)想詞可能會(huì)出現(xiàn)頻繁的變換,直到最后的一個(gè)請(qǐng)求返回。這個(gè)時(shí)候就可以在一定時(shí)間內(nèi)監(jiān)聽(tīng)是否再次輸入,如果沒(méi)有再次輸入則認(rèn)為本次輸入完成,發(fā)送請(qǐng)求,否則就是判定用戶仍在輸入,不發(fā)送請(qǐng)求。
去抖和節(jié)流是不同的,因?yàn)楣?jié)流雖然中間的處理函數(shù)被限制了,但是只是減少了頻率,而去抖則把中間的處理函數(shù)全部過(guò)濾掉了,只執(zhí)行規(guī)判定時(shí)間內(nèi)的最后一個(gè)事件。
2、JS實(shí)現(xiàn)。
前面BB了這么多,感謝你耐心的看到這里,接下來(lái)我們來(lái)自己動(dòng)手看看如何實(shí)現(xiàn)節(jié)流和去抖。
節(jié)流:
/** 實(shí)現(xiàn)思路: ** 參數(shù)需要一個(gè)執(zhí)行的頻率,和一個(gè)對(duì)應(yīng)的處理函數(shù), ** 內(nèi)部需要一個(gè)lastTime 變量記錄上一次執(zhí)行的時(shí)間 **/ function throttle (func, wait) { let lastTime = null // 為了避免每次調(diào)用lastTime都被清空,利用js的閉包返回一個(gè)function確保不生命全局變量也可以 return function () { let now = new Date() // 如果上次執(zhí)行的時(shí)間和這次觸發(fā)的時(shí)間大于一個(gè)執(zhí)行周期,則執(zhí)行 if (now - lastTime - wait > 0) { func() lastTime = now } } }
新聞熱點(diǎn)
疑難解答
圖片精選