函數(shù)防抖和函數(shù)節(jié)流

概念

函數(shù)防抖(debounce)

當(dāng)調(diào)用動作過n毫秒后皆愉,才會執(zhí)行該動作嚷炉,若在這n毫秒內(nèi)又調(diào)用此動作則將重新計(jì)算執(zhí)行時間

函數(shù)節(jié)流(throttle)

預(yù)先設(shè)定一個執(zhí)行周期舞蔽,當(dāng)調(diào)用動作的時刻大于等于執(zhí)行周期則執(zhí)行該動作租副,然后進(jìn)入下一個新周期

函數(shù)節(jié)流(throttle)函數(shù)防抖(debounce)都是為了限制函數(shù)的執(zhí)行頻次抗愁,以優(yōu)化函數(shù)觸發(fā)頻率過高導(dǎo)致的響應(yīng)速度跟不上觸發(fā)頻率郑藏,出現(xiàn)延遲衡查,假死或卡頓的現(xiàn)象。

比如如下的情況:

1. window對象的resize(用于把窗口大小調(diào)整為指定的寬度和高度)必盖、scroll(把內(nèi)容滾動指定的像素?cái)?shù))事件

2. 拖拽時的mousemove事件

3. 文字輸入拌牲、自動完成的keyup事件

區(qū)別

可以拿我們平時坐電梯為例來形象地表述二者的區(qū)別

函數(shù)防抖:如果有人進(jìn)電梯(觸發(fā)事件),那電梯將在10秒鐘后出發(fā)(執(zhí)行事件監(jiān)聽器)歌粥,這時如果又有人進(jìn)電梯了(在10秒內(nèi)再次觸發(fā)該事件)们拙,我們又得等10秒再出發(fā)(重新計(jì)時)。

函數(shù)節(jié)流:保證如果電梯第一個人進(jìn)來后阁吝,10秒后準(zhǔn)時運(yùn)送一次砚婆,這個時間從第一個人上電梯開始計(jì)時,不等待,如果沒有人装盯,則不運(yùn)行

實(shí)現(xiàn)

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

// 函數(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)是芹敌,聲明一個變量當(dāng)標(biāo)志位,記錄當(dāng)前代碼是否在執(zhí)行垮抗。

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

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

這個方法的作用是監(jiān)聽ID為throttle元素的滾動事件。

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

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

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

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

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

三锄贷、函數(shù)防抖

?函數(shù)防抖的應(yīng)用場景译蒂,最常見的就是用戶注冊時候的手機(jī)號碼驗(yàn)證和郵箱驗(yàn)證了。只有等用戶輸入完畢后谊却,前端才需要檢查格式是否正確柔昼,如果不正確,再彈出提示語炎辨。以下還是以頁面元素滾動監(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ù)防抖的要點(diǎn)碴萧,也是需要一個setTimeout來輔助實(shí)現(xiàn)乙嘀。延遲執(zhí)行需要跑的代碼。

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

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

這個方法的作用是監(jiān)聽ID為debounce元素的滾動事件

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

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

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

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

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

其實(shí)履磨,用隊(duì)列的方式也可以做到這種效果。這里就不深入了庆尘。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末剃诅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子驶忌,更是在濱河造成了極大的恐慌矛辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異如筛,居然都是意外死亡堡牡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門杨刨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晤柄,“玉大人,你說我怎么就攤上這事妖胀〗婢保” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵赚抡,是天一觀的道長爬坑。 經(jīng)常有香客問我,道長涂臣,這世上最難降的妖魔是什么盾计? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮赁遗,結(jié)果婚禮上署辉,老公的妹妹穿的比我還像新娘。我一直安慰自己岩四,他們只是感情好哭尝,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剖煌,像睡著了一般材鹦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耕姊,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天桶唐,我揣著相機(jī)與錄音,去河邊找鬼茉兰。 笑死尤泽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的邦邦。 我是一名探鬼主播安吁,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼燃辖!你這毒婦竟也來了鬼店?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤黔龟,失蹤者是張志新(化名)和其女友劉穎妇智,沒想到半個月后滥玷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巍棱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年惑畴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片航徙。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡如贷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出到踏,到底是詐尸還是另有隱情杠袱,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布窝稿,位于F島的核電站楣富,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏伴榔。R本人自食惡果不足惜纹蝴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踪少。 院中可真熱鬧塘安,春花似錦、人聲如沸秉馏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萝究。三九已至,卻和暖如春锉罐,著一層夾襖步出監(jiān)牢的瞬間帆竹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工脓规, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留栽连,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓侨舆,卻偏偏與公主長得像秒紧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挨下,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容