
防抖(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
為false,是以
timeout
的值 為
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
- 浏覽器播放事件,每個一秒計算一次進度資訊等
輸入框在搜尋内容時,可以控制多少s 在執行請求,避免多次發起請求,節約性能。
input
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
為 null,即為
timeout
, 再次執行
false
throttle
!timeout
true
,再次執行定時器。
通過
的狀态來達到節流的控制
timeout
總結
防抖: 觸發事件後,一定時間後再執行事件,可以
也可以
立即執行
一定時間再執行
節流: 控制流量,在機關時間内隻能請求一次,避免多次觸發事件,影響伺服器性能。
結語
❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創作更好的文章