9012年了,不做不懂函數(shù)防抖和函數(shù)節(jié)流的前端

概述

  • 函數(shù)防抖: 任務(wù)頻繁觸發(fā)的情況下,只有任務(wù)觸發(fā)的間隔超過指定間隔的時候,任務(wù)才會執(zhí)行。
  • 函數(shù)節(jié)流: 指定時間間隔內(nèi)只會執(zhí)行一次任務(wù),原本可能會無時無刻執(zhí)行的函數(shù)。

總之都是為了節(jié)省計算資源。

函數(shù)防抖(debounce)

場景:

  • 如今很多網(wǎng)站為了提高用戶體驗,不會再輸入框失去焦點的時候再去判斷用戶名是否被占用,而是在輸入的時候就在判斷這個用戶名是否已被注冊。當用戶輸入第一個字符后的一段時間內(nèi)如果還有字符輸入的話,那就暫時不去請求判斷用戶名是否被占用。
  • 用戶注冊時候的手機號碼驗證和郵箱驗證

任務(wù)頻繁觸發(fā)的情況下,只有足夠的空閑時間,才執(zhí)行代碼一次。

基本思想:通過閉包保存一個標記(timeout)來保存 setTimeout 返回的值,每當用戶輸入的時候把前一個 setTimeout clear 掉,然后又創(chuàng)建一個新的 setTimeout,這樣就能保證輸入字符后的 interval 間隔內(nèi)如果還有字符輸入的話,就不會執(zhí)行 fn 函數(shù)了。

函數(shù)防抖的要點:也是需要一個setTimeout來輔助實現(xiàn)。延遲執(zhí)行需要跑的代碼。
如果方法多次觸發(fā),則把上次記錄的延遲執(zhí)行代碼用clearTimeout清掉,重新開始。
如果計時完畢,沒有方法進來訪問觸發(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)致瀏覽器掛起,有時候甚至會崩潰。比如:onresize、onscroll、mousemove等。

為了避免類似問題,就可以使用定時器對該函數(shù)進行節(jié)流。

基本思想:某些代碼不可以在沒有間斷的情況下連續(xù)重復(fù)執(zhí)行,就是一定時間內(nèi)函數(shù)只執(zhí)行一次。

第一次調(diào)用函數(shù),創(chuàng)建一個定時器,在指定的時間間隔之后運行代碼。當?shù)诙握{(diào)用函數(shù)時,它會清除前一次的定時器并設(shè)置另一個。如果前一個定時器尚未執(zhí)行,就是將其替換為一個新的定時器,目的是只有在執(zhí)行函數(shù)的請求停止了一段時間之后才執(zhí)行。

函數(shù)節(jié)流的要點:聲明一個變量(resizeTimeout)當標志位,記錄當前代碼是否在執(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冷卻時間過了,才可以再放。


    王者英雄王昭君

像這樣,是不是就好理解這兩個概念了

最后編輯于
?著作權(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)容