溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中函數(shù)節(jié)流與函數(shù)防抖的區(qū)別是什么

發(fā)布時(shí)間:2021-01-22 15:59:05 來源:億速云 閱讀:224 作者:Leah 欄目:web開發(fā)

今天就跟大家聊聊有關(guān)JavaScript中函數(shù)節(jié)流與函數(shù)防抖的區(qū)別是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

一、概念解釋

函數(shù)節(jié)流和函數(shù)防抖,兩者都是優(yōu)化高頻率執(zhí)行js代碼的一種手段。

大家大概都知道舊款電視機(jī)的工作原理,就是一行行得掃描出色彩到屏幕上,然后組成一張張圖片。由于肉眼只能分辨出一定頻率的變化,當(dāng)高頻率的掃描,人類是感覺不出來的。反而形成一種視覺效果,就是一張圖。就像高速旋轉(zhuǎn)的風(fēng)扇,你看不到扇葉,只看到了一個(gè)圓一樣。

同理,可以類推到j(luò)s代碼。在一定時(shí)間內(nèi),代碼執(zhí)行的次數(shù)不一定要非常多。達(dá)到一定頻率就足夠了。因?yàn)榕艿迷蕉?,帶來的效果也是一樣。倒不如,把js代碼的執(zhí)行次數(shù)控制在合理的范圍。既能節(jié)省瀏覽器CPU資源,又能讓頁面瀏覽更加順暢,不會(huì)因?yàn)閖s的執(zhí)行而發(fā)生卡頓。這就是函數(shù)節(jié)流和函數(shù)防抖要做的事。

函數(shù)節(jié)流是指一定時(shí)間內(nèi)js方法只跑一次。比如人的眨眼睛,就是一定時(shí)間內(nèi)眨一次。這是函數(shù)節(jié)流最形象的解釋。

函數(shù)防抖是指頻繁觸發(fā)的情況下,只有足夠的空閑時(shí)間,才執(zhí)行代碼一次。比如生活中的坐公交,就是一定時(shí)間內(nèi),如果有人陸續(xù)刷卡上車,司機(jī)就不會(huì)開車。只有別人沒刷卡了,司機(jī)才開車。

二、函數(shù)節(jié)流

函數(shù)節(jié)流應(yīng)用的實(shí)際場(chǎng)景,多數(shù)在監(jiān)聽頁面元素滾動(dòng)事件的時(shí)候會(huì)用到。因?yàn)闈L動(dòng)事件,是一個(gè)高頻觸發(fā)的事件。以下是監(jiān)聽頁面元素滾動(dòng)的示例代碼:

// 函數(shù)節(jié)流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
 if(!canRun){
 // 判斷是否已空閑,如果在執(zhí)行中,則直接return
 return;
 }
 canRun = false;
 setTimeout(function(){
 console.log("函數(shù)節(jié)流");
 canRun = true;
 }, 300);
};

函數(shù)節(jié)流的要點(diǎn)是,聲明一個(gè)變量當(dāng)標(biāo)志位,記錄當(dāng)前代碼是否在執(zhí)行。

如果空閑,則可以正常觸發(fā)方法執(zhí)行。

如果代碼正在執(zhí)行,則取消這次方法執(zhí)行,直接return。

這個(gè)方法的作用是監(jiān)聽I(yíng)D為throttle元素的滾動(dòng)事件。

當(dāng)canRun為true,則代表現(xiàn)在的滾動(dòng)處理事件是空閑的,可以使用。

通過關(guān)卡if(!canRun),等于就拿到了通行證。然后下一步的操作就是立馬將關(guān)卡關(guān)上canRun=false。這樣,其他請(qǐng)求執(zhí)行滾動(dòng)事件的方法,就被擋回去了。

接著用setTimeout規(guī)定最小的時(shí)間間隔300,接著再執(zhí)行setTimeout方法體里面的內(nèi)容。

最后,等setTimeout里面的方法都執(zhí)行完畢,才釋放關(guān)卡canRun=true,允許下一個(gè)訪問者進(jìn)來。

這個(gè)函數(shù)節(jié)流的實(shí)現(xiàn)形式,需要注意的是執(zhí)行的間隔時(shí)間是>=300ms。如果具體執(zhí)行的方法是包含callback的,也可以將canRun=true這一步放到callback中。理解了函數(shù)節(jié)流的關(guān)卡設(shè)置重點(diǎn),其實(shí)改起來就簡(jiǎn)單多了。

三、函數(shù)防抖

函數(shù)防抖的應(yīng)用場(chǎng)景,最常見的就是用戶注冊(cè)時(shí)候的手機(jī)號(hào)碼驗(yàn)證和郵箱驗(yàn)證了。只有等用戶輸入完畢后,前端才需要檢查格式是否正確,如果不正確,再彈出提示語。以下還是以頁面元素滾動(dòng)監(jiān)聽的例子,來進(jìn)行解析:

// 函數(shù)防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
 clearTimeout(timer); // 清除未執(zhí)行的代碼,重置回初始化狀態(tài)
 timer = setTimeout(function(){
 console.log("函數(shù)防抖");
 }, 300);
};

函數(shù)節(jié)流的要點(diǎn),也是需要一個(gè)setTimeout來輔助實(shí)現(xiàn)。延遲執(zhí)行需要跑的代碼。

如果方法多次觸發(fā),則把上次記錄的延遲執(zhí)行代碼用clearTimeout清掉,重新開始。

如果計(jì)時(shí)完畢,沒有方法進(jìn)來訪問觸發(fā),則執(zhí)行代碼。

這個(gè)方法的作用是監(jiān)聽I(yíng)D為debounce元素的滾動(dòng)事件

進(jìn)入滾動(dòng)事件方法體的時(shí)候,做的第一件事就是清除上次未執(zhí)行的setTimeout。而setTimeout的引用id由變量timer記錄。

clearTimeout方法,允許傳入無效的值。所以這里直接執(zhí)行clearTimeout即可。

然后,將需要執(zhí)行的代碼放入setTimeout中,再返回setTimeout引用給timer緩存。

如果倒計(jì)時(shí)300ms以后,還沒有新的方法觸發(fā)滾動(dòng)事件,則執(zhí)行setTimeout中的代碼。

函數(shù)防抖的實(shí)現(xiàn)重點(diǎn),就是巧用setTimeout做緩存池,而且可以輕易地清除待執(zhí)行的代碼。

看完上述內(nèi)容,你們對(duì)JavaScript中函數(shù)節(jié)流與函數(shù)防抖的區(qū)別是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI