JavaScript 中的函數(shù)防抖動與節(jié)流

摘要:JavaScript 中的函數(shù)防抖和節(jié)流是很常用的需求,前端面試也是頻率比較高被問到的知識,本文就通過二者的概念、實現(xiàn)思路家妆、示例代碼和應用場景來介紹一下它們。


概念

  • 函數(shù)防抖(debounce):其概念其實是從機械開關和繼電器的“去彈跳”(debounce)衍生出來的冕茅,基本思路就是把多個信號合并為一個信號伤极。比如一個 input 每當輸入結束后兩秒執(zhí)行搜索事件,這就是個很經(jīng)典的防抖需求姨伤。

  • 函數(shù)節(jié)流(throttle):節(jié)流的概念可以想象一下水壩哨坪,你建了水壩在河道中,不能讓水流動不了乍楚,你只能讓水流慢些当编。換言之,你不能讓用戶的方法都不執(zhí)行徒溪。如果這樣干忿偷,就是debounce了。為了讓用戶的方法在某個時間段內(nèi)只執(zhí)行一次臊泌,我們需要保存上次執(zhí)行的時間點與定時器鲤桥。

思路

  • 函數(shù)防抖的實現(xiàn)思路如下:將目標方法(動作)包裝在setTimeout里面,然后這個方法是一個事件的回調(diào)函數(shù)渠概,如果這個回調(diào)一直執(zhí)行茶凳,那么這些動作就一直不執(zhí)行。為什么不執(zhí)行呢高氮,我們設置了一個clearTimeout慧妄,這樣setTimeout里的方法就不會執(zhí)行! 為什么要clearTimeout呢剪芍,我們就需要將事件內(nèi)的連續(xù)動作刪掉嘛塞淹!待到用戶不觸發(fā)這事件了。那么setTimeout就自然會執(zhí)行這個方法罪裹。

  • 函數(shù)節(jié)流的實現(xiàn)思路如下:某些代碼不可以在沒有間斷的情況連續(xù)重復執(zhí)行饱普。第一次調(diào)用函數(shù),創(chuàng)建一個定時器状共,在指定的時間間隔之后運行代碼套耕。當?shù)诙握{(diào)用該函數(shù)時,它會清除前一次的定時器并設置另一個峡继。如果前一個定時器已經(jīng)執(zhí)行過了冯袍,這個操作就沒有任何意義。然而,如果前一個定時器尚未執(zhí)行康愤,其實就是將其替換為一個新的定時器儡循。目的是只有在執(zhí)行函數(shù)的請求停止了一段時間之后才執(zhí)行。

代碼

函數(shù)防抖示例代碼:

function debounce(func, delay) {
    let timeout
    return function(e) {
        clearTimeout(timeout)
        let args = arguments
        timeout = setTimeout(() => {
          func.apply(this, args)
        },delay)
    }
}

var validate = debounce(function(e) {
    console.log( e.target.value)
}, 2000)

document.querySelector("input").addEventListener('input', validate)

函數(shù)節(jié)流示例代碼:

function debounce(func, delay) {
    let timeout
    return function(e) {
        clearTimeout(timeout)
        let args = arguments
        timeout = setTimeout(() => {
          func.apply(this, args)
        },delay)
    }
}

var validate = debounce(function(e) {
    console.log( e.target.value)
}, 2000)

document.querySelector("input").addEventListener('input', validate)

應用場景

防抖 debounce 多用于 “ 延遲多久后觸發(fā) ”

具體用于input輸入框架的格式驗證征冷,假如只是驗證都是字母也罷了择膝,太簡單了,不怎么耗性能检激,如果是驗證是否身份證肴捉,這性能消耗大,你可以隔170ms才驗證一次叔收。這時就需要這個東西齿穗。或者你這個是自動完全今穿,需要將已有的輸入數(shù)據(jù)往后端拉一個列表缤灵,頻繁的交互,后端肯定耗不起蓝晒,這時也需要這個腮出,如隔 350ms 。
所以大致就有以下兩種應用情景:

  • 每次 resize/scroll 觸發(fā)統(tǒng)計事件
  • 文本輸入的驗證(連續(xù)輸入文字后發(fā)送 AJAX 請求進行驗證芝薇,驗證一次就好)

節(jié)流 throttle 多用于 “ 多久觸發(fā)一次 ”

函數(shù)節(jié)流會用在比input, keyup更頻繁觸發(fā)的事件中胚嘲,如resize, touchmove, mousemove, scroll。throttle 會強制函數(shù)以固定的速率執(zhí)行洛二。因此這個方法比較適合應用于動畫相關的場景馋劈。

  • DOM 元素的拖拽功能實現(xiàn)(mousemove)
  • 射擊游戲的 mousedown/keydown 事件(單位時間只能發(fā)射一顆子彈)
  • 計算鼠標移動的距離(mousemove)
  • Canvas 模擬畫板功能(mousemove)
  • 搜索聯(lián)想(keyup)
  • 監(jiān)聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 后,只有用戶停止?jié)L動后晾嘶,才會判斷是否到了頁面底部妓雾;如果是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次

相關鏈接

(END)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垒迂,一起剝皮案震驚了整個濱河市械姻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌机断,老刑警劉巖楷拳,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吏奸,居然都是意外死亡欢揖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門奋蔚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來她混,“玉大人,你說我怎么就攤上這事〔希” “怎么了棵磷?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晋涣。 經(jīng)常有香客問我,道長沉桌,這世上最難降的妖魔是什么谢鹊? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮留凭,結果婚禮上佃扼,老公的妹妹穿的比我還像新娘。我一直安慰自己蔼夜,他們只是感情好兼耀,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著求冷,像睡著了一般瘤运。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匠题,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天拯坟,我揣著相機與錄音,去河邊找鬼韭山。 笑死郁季,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的钱磅。 我是一名探鬼主播梦裂,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盖淡!你這毒婦竟也來了年柠?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤禁舷,失蹤者是張志新(化名)和其女友劉穎彪杉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牵咙,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡派近,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了洁桌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渴丸。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谱轨,到底是詐尸還是另有隱情戒幔,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布土童,位于F島的核電站诗茎,受9級特大地震影響,放射性物質發(fā)生泄漏献汗。R本人自食惡果不足惜敢订,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罢吃。 院中可真熱鬧楚午,春花似錦、人聲如沸尿招。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽就谜。三九已至怪蔑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吁伺,已是汗流浹背饮睬。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留篮奄,地道東北人捆愁。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像窟却,于是被迫代替她去往敵國和親昼丑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容