在平時的開發中,常常會聽到兩個差很少很相近的詞。節流(throttle)和防抖(debounce)。這是兩個相似又有些不一樣的優化方案。react
節流:在指定時間以內,讓函數只觸發一次。
防抖:對於必定時間段的連續的函數調用,只讓其執行一次。ajax
兩個方法在underscore.js中都已經實現了。本文將會重點說明兩個函數的應用場景和背後的原理。瀏覽器
throttle在英語裏的意思是節流閥,顧名思義,設置一個閥值(制定一個時間),在這個閥值或者時間以內,函數只會執行一次。閉包
舉個例子,咱們執行頁面滾動的時候,好比在react裏面,可能每次滾動都會觸發一次render,這樣嚴重影響性能,甚至會形成瀏覽器卡死。若是咱們設置一個300ms的時間閥,那麼在這段時間內,滾動時候只會觸發一次render.app
一樣的,當咱們拖拽某個元素的時候,會每次判斷mousemove時跟位置相關的信息,每次都會執行相關的計算和判斷,這種狀況就和滾動時候同樣,若是設置一個時間閥,那麼就能夠避免因爲大量執行事件計算而形成的性能降低。函數
我本身的理解,防抖的意思能夠認爲是,阻止連續的抖動(所謂的事件觸發),也就是說,咱們用防抖來讓那些連續觸發的事件只觸發一次。性能
好比,當咱們對一個文本框進行輸入的時候,在react中,每次都會觸發onChange事件,咱們可能在每次事件裏發送ajax請求,判斷輸入的用戶名是否曾經註冊過,這種狀況下咱們使用防抖,能夠保證只會在最後一次onChange事件纔會觸發ajax請求。優化
節流this
節流實現起來很好理解,設置一個bool值,在時間閥以內,根據這個bool來判斷是否執行函數。code
function throttle(fn,times = 300){ let bool = true return function(){ if(!bool){ return false } bool = false setTimeout(()=>{ bool = true fn.apply(this,arguments) },times) } }
防抖
防抖實現起來的思路是,用閉包保存執行的函數,屢次執行的時候把上一個執行的函數清除掉,而後再次建立一個新的函數。這樣在間隔時間內還有事件觸發的話,不會執行以前的函數,這麼一來,函數真正的執行就是最後一次事件觸發。
function debounce(fn,times){ let timeout = null return function(){ clearTimeout(timeout) timeout = setTimeout(()=>{ fn.apply(this,arguments) },times) } }
以上只是很簡單的寫了一下節流和防抖的原理,在underscore.js裏,實現起來更加複雜,可是背後的原理核心就是上邊代碼寫的。二者都是在密集調用的過程當中靈活使用setTimeout函數來對頻繁觸發的事件進行控制和優化。