JavaScript 函數節流和函數去抖應用場景辨析

概述

也是很久沒更新 源碼解讀,看着房價蹭蹭暴漲,內心也是五味雜陳,對將來充滿恐懼和迷茫 ...(敢問一句大家上岸了嗎)html

言歸正傳,今天要介紹的是 underscore 中兩個重要的方法,函數節流和函數去抖。這篇文章不會涉及具體的代碼實現(關於代碼實現請期待下文),會從零開始介紹函數節流和函數去抖的概念,辨析應用場景。爲何我對這兩個方法情有獨鍾要花大篇幅去介紹?由於就是它們帶我入了「underscore 源碼解讀」的坑(詳見 一次發現underscore源碼bug的經歷以及對學術界『拿來主義』的思考)。git

函數節流和去抖的出現場景,通常都伴隨着客戶端 DOM 的事件監聽。舉個例子,實現一個原生的拖拽功能(不能用 H5 Drag&Drop API),須要一路監聽 mousemove 事件,在回調中獲取元素當前位置,而後重置 dom 的位置(樣式改變)。若是咱們不加以控制,每移動必定像素而觸發的回調數量是會很是驚人的,回調中又伴隨着 DOM 操做,繼而引起瀏覽器的重排與重繪,性能差的瀏覽器可能就會直接假死,這樣的用戶體驗是很是糟糕的。咱們須要作的是下降觸發回調的頻率,好比讓它 500ms 觸發一次,或者 200ms,甚至 100ms,這個閾值不能太大,太大了拖拽就會失真,也不能過小,過小了低版本瀏覽器可能就會假死,這樣的解決方案就是函數節流,英文名字叫「throttle」。函數節流的核心是,讓一個函數不要執行得太頻繁,減小一些過快的調用來節流。github

說完函數節流,再看它的好基友函數去抖(debounce)。思考這樣一個場景,對於瀏覽器窗口,每作一次 resize 操做,發送一個請求,很顯然,咱們須要監聽 resize 事件,可是和 mousemove 同樣,每縮小(或者放大)一次瀏覽器,實際上會觸發 N 屢次的 resize 事件,用節流?節流只能保證定時觸發,咱們一次就好,這就要用去抖。簡單的說,函數去抖就是對於必定時間段的連續的函數調用,只讓其執行一次。瀏覽器

throttle 應用場景

函數節流有哪些應用場景?哪些時候咱們須要間隔必定時間觸發回調來控制函數調用頻率?dom

  • DOM 元素的拖拽功能實現(mousemove)函數

  • 射擊遊戲的 mousedown/keydown 事件(單位時間只能發射一顆子彈)性能

  • 計算鼠標移動的距離(mousemove)htm

  • Canvas 模擬畫板功能(mousemove)blog

  • 搜索聯想(keyup)遊戲

  • 監聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 後,只有用戶中止滾動後,纔會判斷是否到了頁面底部;若是是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次 https://github.com/hanzichi/u...

debounce 應用場景

函數去抖有哪些應用場景?哪些時候對於連續的事件響應咱們只須要執行一次回調?

  • 每次 resize/scroll 觸發統計事件

  • 文本輸入的驗證(連續輸入文字後發送 AJAX 請求進行驗證,驗證一次就好)

小結

函數節流和函數去抖的核心其實就是限制某一個方法被頻繁觸發,而一個方法之因此會被頻繁觸發,大多數狀況下是由於 DOM 事件的監聽回調,而這也是函數節流以及去抖多數狀況下的應用場景。至於函數節流和去抖方法的具體代碼實現以及調用方式,下文咱們再作分享。

附另外兩篇關於 underscore 函數節流以及去抖源碼剖析的文章

相關文章
相關標籤/搜索