函數(shù)的防抖與節(jié)流-js

函數(shù)函數(shù)我們先來看一看防抖和節(jié)流比較精煉的定義:

防抖: 指觸發(fā)事件后在 n 秒內(nèi)函數(shù)只能執(zhí)行一次秩铆,如果在 n 秒內(nèi)又觸發(fā)了事件功氨,則會重新計算函數(shù)執(zhí)行時間。

節(jié)流:連續(xù)發(fā)生的事件在n秒內(nèi)只執(zhí)行一次

相信鲤妥,看完上面說的定義后庶橱,有些人還是不能很好的明白他們之間的區(qū)別,那么就接下來談一談我對它們的理解吧童擎。

防抖(debounce)

防抖防抖滴劲,顧名思義,就是防止手抖么顾复,你想一下你手抖會干什么(班挖??芯砸?停止開車)比如一個按鈕萧芙,點一下向服務(wù)器發(fā)送一個請求,你手一抖假丧,點了好幾下双揪,一下就向服務(wù)器發(fā)了好幾次請求,這不浪費時間資源么包帚。這時候渔期,就要有個防抖函數(shù)來幫幫你了。

當(dāng)你點擊這個按鈕后渴邦,不管你手怎么抖疯趟,一直抖個不停的點這個按鈕,都只向服務(wù)器發(fā)送一次請求谋梭,只有過了一段時間后迅办,確定了你手不再抖后(在這一段時間你都沒有再點這個按鈕),你再去點擊這個按鈕章蚣,才會再次向服務(wù)器發(fā)送請求站欺。

下面分析一下代碼姨夹,你一定會更加的明白:

/*
@function 防抖函數(shù)(最后執(zhí)行)
@param func {Function} 要執(zhí)行的函數(shù)
@para wait {Number} 判斷手不抖的時間
*/
const debounce=(func,wait)=>{
    let timeout;    //不能定義到里面,否則每次調(diào)用里面的函數(shù)矾策,都會對timeout重新賦值
    return function(){
        if(timeout) clearTimeout(timeout) //這里使用timeout產(chǎn)生了閉包
        timeout = setTimeout(function(){
            func.apply(this)
        },wait)
    }
}
function btnClick(){
    console.log('發(fā)送一次請求')
}
$('#myBtn').click(debounce(btnClick,3000));

首先會執(zhí)行第18行的debounce函數(shù)磷账,返回一個匿名函數(shù)作為按鈕點點擊的回調(diào)。當(dāng)點擊一次按鈕的時候贾虽,timeout為undefined逃糟,會執(zhí)行第10行的代碼,設(shè)置一個定時器蓬豁。當(dāng)你手抖(在wait時間內(nèi)有點擊了按鈕)的時候绰咽,會執(zhí)行第9行,將上一個定時器清除地粪,然后再設(shè)置一個新的定時器取募。只有你手不抖了(在wait時間內(nèi)沒有點擊按鈕),就會執(zhí)行第11行蟆技,執(zhí)行點擊按鈕所要發(fā)送的請求服務(wù)玩敏。

可以看出來,這個防抖函數(shù)质礼,是再確定你手不抖前的最后一次點擊才發(fā)送的請求數(shù)據(jù)旺聚。但有時候你并不想這樣啊,你覺得眶蕉,當(dāng)我第一次點擊的時候就要發(fā)送數(shù)據(jù)砰粹,至于后面我手抖,你控制不讓我發(fā)不久好了造挽,這樣我手抖的時候碱璃,發(fā)現(xiàn)數(shù)據(jù)已經(jīng)請求過來了,我一高興刽宪,手不就不抖了厘贼,好的,滿足你的要求圣拄。

/*
@function 防抖函數(shù)(最初執(zhí)行)
@param func {Function} 要執(zhí)行的函數(shù)
@para wait {Number} 判斷手不抖的時間
*/
const debounce=(func,wait)=>{
    let timeout;    
    return function(){
        if(timeout){
            clearTimeout(timeout);
        }else{
            func.apply(this)
        }
         timeout = setTimeout(function(){
            timeout =null
        },wait)
    }
}
function btnClick(){
    console.log('發(fā)送一次請求')
}
$('#myBtn').click(debounce(btnClick,3000));

相當(dāng)于嘴秸,在第一次點擊,還沒有設(shè)置定時器的時候庇谆,就先執(zhí)行請求數(shù)據(jù)的函數(shù)岳掐,然后設(shè)置定時器用來防抖,后面不管怎么抖饭耳,timeout值都存在串述,只有再不抖后,才會將timeout設(shè)置為null寞肖,然后再點擊的時候就又能請求數(shù)據(jù)了纲酗。

節(jié)流(throttle)

節(jié)流節(jié)流衰腌,顧名思義就是節(jié)省流量了,你想想觅赊,怎么才能節(jié)省流量右蕊。那不就減少請求唄。1秒請求3次吮螺,我改成3秒請求1次饶囚,那流量還不妥妥的節(jié)省下來了。就比如鸠补,你一個搜索框萝风,按一下鍵盤向服務(wù)器發(fā)送一次請求,卡卡的紫岩,頁面一直跟著你敲鍵盤在變化规惰,你給老板說,看帥不被因,實時動態(tài)搜索卿拴,這時候老板上來就給你兩耳刮子衫仑,說著梨与,我可算知道為啥一個小項目就要買這么好的服務(wù)器了,都是你這玩意霍霍的文狱。這時候粥鞋,節(jié)流就能幫助到你了,設(shè)置個時間瞄崇,這個時間內(nèi)呻粹,不管怎么敲鍵盤,只請求一次數(shù)據(jù)苏研,差不多輸一個單詞請求一次等浊,大大節(jié)省了后臺的壓力,你的動態(tài)搜索也能夠很好的實現(xiàn)摹蘑。

估計這個還是比較好理解的筹燕,直接看代碼就好了。

/*
@function 節(jié)流函數(shù)
@param func {Function} 要執(zhí)行的函數(shù)
@para wait {Number} 時間間隔
*/
const throttle=(func,wait)=>{
    let previous  = 0;
    return function(){
        let nowtime = Date.now();
        if(nowtime-previous>wait){
            func.apply(this);
            previous = nowtime;
        }
    }
}
function keyUp(){
    console.log('搜索一次')
}
$('#myInput').keyup(throttle(btnClick,1000));

這個代碼也比較好理解衅鹿,每次按鍵抬起的時候撒踪,都會判斷當(dāng)前的時間和上一次執(zhí)行搜索功能的時間的差值,判斷要不要再進(jìn)行一次搜索大渤。

好了制妄,函數(shù)的防抖與節(jié)流的區(qū)別和實現(xiàn)應(yīng)該很清楚了。

最后不得不感慨泵三,中華文化的博大精深以及前輩們翻譯時的智慧耕捞,debounce與throttle對應(yīng)防抖與節(jié)流衔掸,讓這兩個很容易搞混的概念一下子就變得如此清晰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俺抽,一起剝皮案震驚了整個濱河市具篇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凌埂,老刑警劉巖驱显,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞳抓,居然都是意外死亡埃疫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門孩哑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栓霜,“玉大人,你說我怎么就攤上這事横蜒「炻” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵丛晌,是天一觀的道長仅炊。 經(jīng)常有香客問我,道長澎蛛,這世上最難降的妖魔是什么抚垄? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮谋逻,結(jié)果婚禮上呆馁,老公的妹妹穿的比我還像新娘。我一直安慰自己毁兆,他們只是感情好浙滤,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著气堕,像睡著了一般纺腊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上送巡,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天摹菠,我揣著相機與錄音,去河邊找鬼骗爆。 笑死次氨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摘投。 我是一名探鬼主播煮寡,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼虹蓄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了幸撕?” 一聲冷哼從身側(cè)響起薇组,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坐儿,沒想到半個月后律胀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡貌矿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年炭菌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逛漫。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡黑低,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酌毡,到底是詐尸還是另有隱情克握,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布枷踏,位于F島的核電站菩暗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏呕寝。R本人自食惡果不足惜勋眯,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一婴梧、第九天 我趴在偏房一處隱蔽的房頂上張望下梢。 院中可真熱鬧,春花似錦塞蹭、人聲如沸孽江。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岗屏。三九已至,卻和暖如春漱办,著一層夾襖步出監(jiān)牢的瞬間这刷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工娩井, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留暇屋,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓洞辣,卻偏偏與公主長得像咐刨,于是被迫代替她去往敵國和親昙衅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350