概述
- 函數(shù)防抖: 任務(wù)頻繁觸發(fā)的情況下奔滑,只有任務(wù)觸發(fā)的間隔超過指定間隔的時候,任務(wù)才會執(zhí)行顺少。
- 函數(shù)節(jié)流: 指定時間間隔內(nèi)只會執(zhí)行一次任務(wù)朋其,原本可能會無時無刻執(zhí)行的函數(shù)王浴。
總之都是為了節(jié)省計算資源。
函數(shù)防抖(debounce)
場景:
- 如今很多網(wǎng)站為了提高用戶體驗令宿,不會再輸入框失去焦點(diǎn)的時候再去判斷用戶名是否被占用叼耙,而是在輸入的時候就在判斷這個用戶名是否已被注冊。當(dāng)用戶輸入第一個字符后的一段時間內(nèi)如果還有字符輸入的話粒没,那就暫時不去請求判斷用戶名是否被占用筛婉。
- 用戶注冊時候的手機(jī)號碼驗證和郵箱驗證
任務(wù)頻繁觸發(fā)的情況下,只有足夠的空閑時間癞松,才執(zhí)行代碼一次爽撒。
基本思想:通過閉包保存一個標(biāo)記(timeout)來保存 setTimeout
返回的值,每當(dāng)用戶輸入的時候把前一個 setTimeout
clear 掉响蓉,然后又創(chuàng)建一個新的 setTimeout
硕勿,這樣就能保證輸入字符后的 interval
間隔內(nèi)如果還有字符輸入的話,就不會執(zhí)行 fn
函數(shù)了枫甲。
函數(shù)防抖的要點(diǎn):也是需要一個setTimeout
來輔助實(shí)現(xiàn)源武。延遲執(zhí)行需要跑的代碼。
如果方法多次觸發(fā)想幻,則把上次記錄的延遲執(zhí)行代碼用clearTimeout
清掉粱栖,重新開始。
如果計時完畢脏毯,沒有方法進(jìn)來訪問觸發(fā)闹究,則執(zhí)行代碼。
// 函數(shù)防抖
function debounce(handlerFunc, interval = 300) {
let timeout = null;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
handlerFunc.apply(this, arguments);
}, interval);
};
}
//綁定監(jiān)聽
window.addEventListener('resize', () => {
debounce(this.onResize, 40)
}, false);
函數(shù)節(jié)流(throttle)
場景:過多的DOM相關(guān)操作可能會導(dǎo)致瀏覽器掛起食店,有時候甚至?xí)罎⒃佟1热纾簅nresize、onscroll吉嫩、mousemove等价认。
為了避免類似問題,就可以使用定時器對該函數(shù)進(jìn)行節(jié)流自娩。
基本思想:某些代碼不可以在沒有間斷的情況下連續(xù)重復(fù)執(zhí)行刻伊,就是一定時間內(nèi)函數(shù)只執(zhí)行一次。
第一次調(diào)用函數(shù)椒功,創(chuàng)建一個定時器捶箱,在指定的時間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用函數(shù)時动漾,它會清除前一次的定時器并設(shè)置另一個丁屎。如果前一個定時器尚未執(zhí)行,就是將其替換為一個新的定時器旱眯,目的是只有在執(zhí)行函數(shù)的請求停止了一段時間之后才執(zhí)行晨川。
函數(shù)節(jié)流的要點(diǎn):聲明一個變量(resizeTimeout)當(dāng)標(biāo)志位证九,記錄當(dāng)前代碼是否在執(zhí)行。
- 如果空閑共虑,則可以正常觸發(fā)方法執(zhí)行愧怜。
- 如果代碼正在執(zhí)行,則取消這次方法執(zhí)行妈拌。
注意:只要是代碼周期性執(zhí)行的拥坛,都應(yīng)該使用節(jié)流,但是并不能控制請求執(zhí)行的速率尘分。
// 函數(shù)節(jié)流
function throttle(handlerFunc, timeout = 66) {
let resizeTimeout;
if (!resizeTimeout) {
resizeTimeout = setTimeout(() => {
resizeTimeout = null;
handlerFunc();
// The actualResizeHandler will execute at a rate of 15fps
}, timeout);
}
}
//綁定監(jiān)聽
window.addEventListener('resize', () => {
throttle(this.onResize, 40)
}, false);
總結(jié)
函數(shù)防抖和函數(shù)節(jié)流的名字起得易混淆猜惋,要找技巧理解記憶,通俗易懂的說:
- 函數(shù)防抖就像快遞小哥先將外賣攢著一起培愁,只有規(guī)定間隔內(nèi)沒有其他配單的時候著摔,才集中送一次。
-
函數(shù)節(jié)流就像王者榮耀中人物釋放技能之后定续,需要CD冷卻時間過了谍咆,才可以再放。
王者英雄王昭君
像這樣私股,是不是就好理解這兩個概念了