關注公衆號, 設置爲 '星標' ,更多精彩內容,第一時間獲取前端
防抖與節流
導讀目錄
node
防抖(debounce)git
防抖應用場景github
非當即執行版web
當即執行版本瀏覽器
合成版本 防抖服務器
節流微信
節流應用場景app
時間戳版本編輯器
定時器版本
總結
參考
1防抖(debounce)
所謂防抖,就是指觸發事件後 n 秒後才執行函數,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。
防抖類型分爲
非當即執行版 當即執行版 合成版本 防抖
防抖應用場景
登陸、發短信等按鈕避免用戶點擊太快,以至於發送了屢次請求 調整瀏覽器窗口大小時,resize 次數過於頻繁,形成計算過多,此時須要一次到位 文本編輯器實時保存,當無任何更改操做一秒後進行保存
非當即執行版
非當即執行版的意思是觸發事件後函數不會當即執行,而是在 n 秒後執行,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。
/**
* @description:
* @param {*} func 觸發的時間
* @param {*} wait 多少時長才執行事件
* @return {*}
*/
function debounce(func, wait) {
let timeout;
return function(){
// 獲取當前做用域和參數
const context = this;
const args = [...arguments]
// 若是當前timeout 存在
// 清空定時器,再次等待wait時間事後再次執行事件
if(timeout) clearTimeout(timeout)
// 定時執行 傳遞進來的事件
timeout = setTimeout(()=>{
func.apply(context,args)
},wait)
}
}
當即執行版本
當即執行版的意思是觸發事件後函數會當即執行,而後 n 秒內不觸發事件才能繼續執行函數的效果。
function debounce(func,wait) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
}
代碼解析
當 執行
debounce
函數時, 第一次進來時,timeout
爲false,因此callNow
的值 爲true
,那麼它會當即執行func
函數,這時timeout
的值 爲true
, 當timeout 值爲true 時
, 會執行 清空定時器,此時 timeout 又爲 false 了
, 這時callNow
又 爲true
,再次執行func
函數。一直循環這樣的操做:
當
timeout
爲false
時,會馬上執行func
函數。當
timeout
爲true
時,它會執行clearTimeOut
,這時timeout
又爲false
, 而callNow
=! timeout
, 就會馬上執行func
函數了。
合成版本 防抖
經過傳遞
Boolean
來決定執行哪一種版本。
true
爲當即執行版false
爲非當即執行版本
debounce(func,1000,true)
/**
* @desc 函數防抖
* @param func 函數
* @param wait 延遲執行毫秒數
* @param immediate true 表當即執行,false 表非當即執行
*/
function debounce(func, wait, immediate) {
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
if (immediate) {
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
}
2節流
所謂節流,就是指連續觸發事件可是在 n 秒中只執行一次函數。 節流會稀釋函數的執行頻率。
節流有兩種實現:
時間戳版本 定時器版本
節流應用場景
scroll
事件,每隔一秒計算一次位置信息等瀏覽器播放事件,每一個一秒計算一次進度信息等 input
輸入框在搜索內容時,能夠控制多少s 在執行請求,避免屢次發起請求,節約性能。
時間戳版本
function throttle(func, wait) {
var previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
定時器版本
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
代碼解析
當執行
throttle
函數時,timeout
默認爲undefined
, 此時,! timeout
爲true
時,執行 定時器,而且 將timeout
爲 null,即爲false
, 再次執行throttle
函數時,!timeout
又爲true
,再次執行定時器。**經過
timeout
的狀態來達到節流的控制 **
3總結
防抖:觸發事件後,必定時間後再執行事件,能夠
當即執行
也能夠必定時間再執行
節流:控制流量,在單位時間內只能請求一次,避免屢次觸發事件,影響服務器性能。
參考
https://github.com/mqyqingfeng/Blog/issues/26
原創不易,素質三連
本文分享自微信公衆號 - 前端自學社區(gh_ce69e7dba7b5)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。