節流 (throttle)與 防抖 (debounce)都是爲了下降調用頻率的一種方式。html
相同點都是須要設置一個回調函數及週期時間,區別在於:react
防抖是在中止觸發後的100ms,執行一次(在此時間段內,只要不中止觸發,理論上就永遠不會觸發回調)git
節流是在不斷的觸發過程當中,每隔100ms就執行一次。github
下面簡單畫下流程圖瀏覽器
在高頻觸發回調函數時,節流操做使回調函數在每隔一段時間按期執行一次,時間間隔內再觸發,不會從新執行。markdown
核心在於讓一個函數不要執行的太頻繁,減小一些過快的操做。less
相似於技能冷卻時間 ⏱ide
/** * 節流 * @param func * @param wait */
function throttle(func: Function, wait: number) {
let timer: number = 0;
return (...args) => {
if (timer) { return }
timer = window.setTimeout(() => {
func(...args)
timer = 0
}, wait)
}
}
複製代碼
在高頻觸發回調函數時,防抖操做使回調函數在必定時間間隔內,再次觸發會清空定時器,並從新計時;計時結束後輸出一次結果。函數
核心在於,在短期內大量觸發同一事件時,只會執行一次回調函數。避免把一次事件誤認爲屢次。oop
/** * 防抖 * @param func * @param wait */
function debounce(func: ()=>void, wait: number) {
let timer: number = 0
return (...args) => {
clearTimeout(timer)
timer = window.setTimeout(() => {
func(...args)
timer = 0; // 必須麼??
}, wait)
}
}
複製代碼
tips: 注意 args 剩餘參數的傳遞,不然執行回調函數時參數將丟失。
🌰 栗子
// 監聽頁面滾動條位置
const handleScrollTop = () => {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滾動條位置:' + scrollTop);
}
// 防抖:在中止滾動100ms後,纔會輸出滾動條位置
window.onscroll = debounce(handleScrollTop,100)
// 節流:每隔100ms都會輸出一次滾動條位置
window.onscroll = throttle(showTop,100)
複製代碼
節流、防抖有時用哪一個均可以,好比監聽頁面滾動,能夠節流(每一個一段時間出發一次回調),也能夠防抖(用戶當前此次滾動結束出發,繼續滾動等待下一次觸發)
須要注意調用節流/防抖函數位置,在組件初始化時就綁定節流/防抖事件,不然回調函數不會被觸發。
constructor(props: any) {
super(props);
// 注意在此綁定!!
this.handleScroll = throttle(this.handleScroll, 100)
}
複製代碼
參考