/*
* 防抖
* 思路:根據定時器的創建與銷燬來判斷是否進行fn操作
* 操作結束後一段時間wait秒內,沒有再次觸發該操作,fn才執行
* 如果wait秒內又觸發了該操作,則重新計時,重新等待wait秒後執行
* 若需要先立即執行一次,在定時器生效前定一個flag
* 業務場景:搜索聯想、防止重複抽獎/支付等
*/
function debounce(fn,wait,rightnow){
let timer = null;
return function () {
let that = this;
let args = arguments;
timer && clearTimeout(timer);
if(rightnow){
let flag = timer;//立即執行
}
timer = setTimeout(()=>{
fn.apply(that,args);
},wait)
if(rightnow && !flag){//立即執行版本
fn.apply(that,args)
}
}
}
let fn = function(){
console.log(document.body.scrollTop ||document.documentElement.scrollTop)
}
window.onscroll = debounce(fn,1000);
/*
* 節流
* 思路: 根據當前時間間隔來判斷是否執行fn
* 對於連續觸發的事件,在一定的時間wait秒內,函數fn只執行一次
* 業務場景:上拉刷新、圖片懶加載等
* */
function throttle(fn,wait) {
let start = 0;
return function loop(){
let now = Date.now();
let flag = now - start - wait,//觸發條件 是否達到要求的時間間隔
that = this,
args = arguments;
if(flag >= 0){
fn.apply(that,args);
start = now;
}
}
}
let fn = function(){
console.log("scrollTop",document.body.scrollTop||document.documentElement.scrollTop)
}
window.onscroll = throttle(fn,1000);
這兩者的區別在於:
防抖需要在特定的操作結束後或者結束時纔會執行(設置的間歇時間wait)次,而節流函數會讓會執行(實際操作持續的時間time/設定的間歇時間wait)次,比如搜索聯想需要在輸入完全結束後才執行聯想功能,纔可以減少請求次數,具有多次抽獎機會時,需要等到第一次抽獎結果返回並執行todos後,才能進行第二次抽獎,這種類型的業務場景我們就選擇防抖函數,而另外,當我們在另一些業務場景時,比如上拉刷新,多次觸發時,當然不需要不斷請求,也不是隻能請求一次,我們需要讓他每隔幾秒請求一次,達到減少請求次數的要求,又能讓用戶對自己多次操作又一定的交互體驗。