函式的防抖與節流目的都是在於減少事件呼叫頻率。
防抖場景:搜尋場景,待使用者停頓進行檢測。
節流場景:驗證碼場景,60秒內不可以再次點選。
防抖與節流的區別
在多次連續執行中,防抖是執行最後一次,節流是執行第一次。比如上面我們提到的搜尋就是檢測使用者最後輸入值,驗證碼就是使用者的第一次點選。
防抖
在前面的事件還沒有執行完畢,又有了新的事件,那麼取消前面的事件,執行新的事件。
var debounce = (fn, wait) => {
let timer = null
return (...value) => {
// 如果前面有待執行的timer,清除timer
if(timer) clearTimeout(timer)
// 構建最新的timer,放入執行佇列
timer = setTimeout(()=>{
fn(value)
}, wait)
}
}
複製程式碼
防抖升級:我們知道按照上面的話,我們在第一次輸入的時候就要進行等待,這是沒有必要的也影響到使用者體驗。 可以優化成:使用者首次輸入,執行不用等待->繼續輸入,進入防抖->抖動結束返回第一步
var debounce = (fn, wait) => {
let timer;
let first = true;
return (...value) => {
if (first) {
first = false;
return fn(value);
}
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn(value);
first = true;
}, wait);
};
};
let con = (...val) => console.log(...val);
let conPlus = debounce(con, 2000);
conPlus("frist");
conPlus("second");
conPlus("last");
複製程式碼
節流
在前面的事件沒有執行完畢,狀態固定為不可執行,待執行完畢後更新狀態。
var throttle = (fn, wait) => {
let canRun = true
return (...value) => {
// 檢測狀態,鎖住狀態則不可二次執行
if(canRun === false){
return
}
/*
* 可執行部分
*/
// 更改狀態為不可執行
canRun = false
// 等待函式執行完畢
setTimeout(() => {
fn(value)
// 執行完畢後修改狀態為可執行狀態
canRun = true
}, wait)
}
}
複製程式碼
看完上面的程式碼,節流是不是很像廁所檢修,檢修員進去先在門口樹一塊“不可用的”警示牌,修好之後把牌子拿走。