好程式設計師分享JS節流和防抖的區分和實現詳解

好程式設計師IT發表於2019-04-03

本文主要介紹的是關於 JS 中比較常用的 函式 :節流 函式 和防抖函式,從概念、使用場景到程式碼簡單實現做了一個詳細的區分。希望對你有所幫助。

在寫 JS 時,這兩個函式比較常見,有時候傻傻分不清用哪個,或者說知道程式碼要怎麼寫,但要說出它究竟是節流函式還是防抖函式時一臉楞逼。今天有一個同學分享了這兩個的區分,我也來回顧一下,加深一下印象,以便日後用到時心裡有底。 PS :百度和谷歌搜尋前幾個介紹都是相反介紹,本文為原創,如有雷同純屬抄襲我的。

節流概念 (Throttle)

按照設定的時間固定執行一次函式,比如 200ms一次。注意:固定就是你在mousemove過程中,執行這個節流函式,它一定是200ms(你設定的定時器延遲時間)內執行一次。沒到200ms,一定會返回,沒有執行回撥函式的。

主要應用場景有: scroll touchmove

防抖概念 (Debounce)

抖動停止後的時間超過設定的時間時執行一次函式。注意:這裡的抖動停止表示你停止了觸發這個函式,從這個時間點開始計算,當間隔時間等於你設定時間,才會執行裡面的回撥函式。如果你一直在觸發這個函式並且兩次觸發間隔小於設定時間,則一定不會到回撥函式那一步。

主要應用場景有: input 驗證、搜尋聯想、 resize

節流實現

思路: 第一次先設定一個變數 true ,第二次執行這個函式時,會判斷變數是否 true ,是則返回。當第一次的定時器執行完函式最後會設定變數為 flase 。那麼下次判斷變數時則為 flase ,函式會依次執行。

程式碼一:首次不執行

function throttle(fn,delay=100){

//首先設定一個變數,在沒有執行我們的定時器時為null

let timer = null;

return function(){

//當我們發現這個定時器存在時,則表示定時器已經在執行中,需要返回

if(timer) return;

timer = setTimeout(()=>{

fn.apply(this,arguments);

timer = null;

},delay);

}

}

程式碼二:首次執行

function throttle2(fn,delay=100){

let last = 0;

return function(){

let curr = +new Date();

if(curr - last > delay){

fn.apply(this,arguments);

last = curr;

}

}

}

防抖實現

思路:首次執行時把定時器賦值給一個變數,第二次執行時,如果間隔沒超過定時器設定的時間則會清除掉定時器,重新設定定時器,依次反覆,當我們停止下來時,沒有執行清除定時器,超過一定時間後觸發回撥函式。

程式碼一:首次不執行

function debounce(fn,delay=200){

let timer = null;

return function(){

if(timer) clearTimeout(timer);

timer = setTimeout(()=>{

fn.apply(this,arguments);

timer = null;

},delay);

}

}

程式碼二:首次執行

//code from debounce2(fn, delay = 200, atBegin = true) {

let timer = null, last = 0,during;

return function () {

let self = this, args = arguments;

var exec = function () {

fn.apply(self, args);

}

if (atBegin && !timer) {

exec();

atBegin = false;

} else {

during = Date.now() - last;

if (during > delay) {

exec();

} else {

if (timer) clearTimeout(timer);

timer = setTimeout(function () {

exec();

}, delay);

}

}

last = Date.now();

}

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2640307/,如需轉載,請註明出處,否則將追究法律責任。

相關文章