
防抖(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);
}
}
}
節流
所謂節流,就是指連續觸發事件但是在 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的狀態來達到節流的控制 **
總結
防抖: 觸發事件后,一定時間后再執行事件,可以
立即執行也可以一定時間再執行節流: 控制流量,在單位時間內只能請求一次,避免多次觸發事件,影響服務器性能。
結語
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創作更好的文章
關注公眾號 前端自學社區,即可獲取更多前端高質量文章!
關注后回復關鍵詞“加群”, 即可加入 “前端自學交流群”,共同學習進步。
關注后添加我微信拉你進技術交流群
歡迎關注公眾號,更多精彩文章只在公眾號推送
