您好,登錄后才能下訂單哦!
函數節流是另一種常見的優化高頻率調用函數的手段,核心是把高頻率調用的函數優化為按照某個時間頻率來執行
函數節流與函數防抖動的區別在于:
函數防抖動是檢測前后兩次連續間隔內的函數調用,并將時間間隔內的多次調用合并為一次;
函數節流是將頻繁的函數調用弱化為按照某個時間間隔來調用。
根據具體的實現方式可以分為兩種,分別是定時器實現以及時間戳實現
當函數調用時,先檢查是否已經存在定時器,如果存在則等待該定時器完成,否則生成一個新的定時器來處理。
根據這個想法,可以大致得到如下代碼:
function throttleByTimer(cb, wait) {
let timer = null;
return function() {
if(timer) return;
timer = setTimeout(() => {
cb.apply(this, arguments);
timer = null;
}, wait);
}
}
當函數調用時,用當前時間戳與上次執行完成的時間戳進行比較,當間隔在等待時間之內,則無視該次函數調用,否則執行回調并記錄時間戳 。
function throttleByTimeStamp(cb, wait) {
let preTimeStamp = +new Date();
return function() {
let nowTimeStamp = +new Date();
if (nowTimeStamp - preTimeStamp < wait) return;
cb.apply(this, arguments);
preTimeStamp = nowTimeStamp;
}
}
對比兩種方式可以發現,定時器的實現無法首次立即執行,而時間戳的實現雖然可以首次立即執行,但無法確保必定執行最后一次回調。而實際業務開發中,為了保證結果的正確性,往往需要確保最后一次回調的執行。
因此,可以優化一下,最終版如下
function throttle(cb, wait) {
let preTimeStamp = 0;
let timer = null;
return function() {
let nowTimeStamp = +new Date();
let difTimeStamp = nowTimeStamp - preTimeStamp;
if (difTimeStamp < wait) {
if (timer) return;
timer = setTimeout(() => {
cb.apply(this, arguments);
timer = null;
preTimeStamp = +new Date();
}, wait - difTimeStamp);
return;
}
clearTimeout(timer);
timer = null;
cb.apply(this, arguments);
preTimeStamp = nowTimeStamp;
}
}
使用方式:
timerPDom.onmousemove = throttle(move, 1000);
mousemove、scroll等頻繁觸發的事件監聽
滾動加載
其他會頻繁調用的函數等
函數節流的優化可以類比成一個水龍頭從不斷滴水改為每隔一個時間間隔滴一次水的過程,既可以收集到水也不會浪費水資源
定時器節流,由于定時器的特性,無法首次立即執行,但可以確保必定會執行最后一次
時間戳節流,可以首次立即執行,但無法確保會執行最后一次
這兩種單一實現的方式各有缺陷,實際應用還需整合起來用
文章來自公眾號:睿江云計算
睿江云官網鏈接:https://www.eflycloud.com/home?from=RJ0024
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。