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

防抖throttle

防抖:當(dāng)事件在短時(shí)間內(nèi)持續(xù)觸發(fā)身坐,在間隔時(shí)間內(nèi)(如1000ms)耿战,只在最后一次觸發(fā)的時(shí)候丁存,執(zhí)行目標(biāo)函數(shù)鱼喉。

就是說(shuō)肺缕,防抖不會(huì)讓函數(shù)立即執(zhí)行,而是1000ms延時(shí)內(nèi)沒(méi)有再次觸發(fā)租冠,才會(huì)執(zhí)行目標(biāo)函數(shù)
實(shí)現(xiàn):通過(guò)setTimeout做延時(shí)處理,如果定時(shí)器不為空薯嗤,則重新延時(shí)顽爹。
應(yīng)用場(chǎng)景:監(jiān)聽(tīng)輸入框keyup。

//防抖
function debounce(fn,delay){
    let timer = null   //借助閉包
    return function() {
        if(timer){
            clearTimeout(timer) 
        }
        timer = setTimeout(fn,delay)   // 簡(jiǎn)化寫(xiě)法
    }
}
//目標(biāo)函數(shù)
function handle(){
  console.log(Math.random())
}
//監(jiān)聽(tīng)防抖
window.onscroll = debounce(handle,1000)

以上代碼的效果就是骆姐,在滾動(dòng)條停止一秒滾動(dòng)之后镜粤,才會(huì)執(zhí)行一次函數(shù),輸出一個(gè)隨機(jī)數(shù)玻褪。

節(jié)流debounce

節(jié)流:函數(shù)間隔一段時(shí)間后才能再觸發(fā)肉渴,避免某些函數(shù)觸發(fā)頻率過(guò)高。

就是說(shuō)带射,保證目標(biāo)函數(shù)在間隔時(shí)間(如1000ms)內(nèi)只執(zhí)行一次
實(shí)現(xiàn):一定時(shí)間內(nèi)只觸發(fā)一次函數(shù)同规,通過(guò)判斷是否達(dá)到一定時(shí)間來(lái)確定是否要執(zhí)行目標(biāo)函數(shù)。
應(yīng)用場(chǎng)景:防止頻繁點(diǎn)擊造成表單多次提交窟社,監(jiān)聽(tīng)滾動(dòng)事件券勺。

//節(jié)流
function throttle(fn,delay){
    let valid = true
    return function() {
       if(!valid){
           //休息時(shí)間 暫不接客
           return false 
       }
       // 工作時(shí)間,執(zhí)行函數(shù)并且在間隔期內(nèi)把狀態(tài)位設(shè)為無(wú)效
        valid = false
        setTimeout(() => {
            fn()
            valid = true;
        }, delay)
    }
}
//目標(biāo)函數(shù)
function handle(){
  console.log(Math.random())
}
//監(jiān)聽(tīng)節(jié)流
window.onscroll = throttle(handle,1000)

以上代碼的效果就是灿里,當(dāng)滾動(dòng)條一直處于滾動(dòng)狀態(tài)時(shí)关炼,每隔一秒輸出一個(gè)隨機(jī)數(shù)。

總結(jié):(當(dāng)持續(xù)觸發(fā)時(shí))防抖讓事件只在最后一次發(fā)生匣吊。節(jié)流讓事件每隔一段時(shí)間觸發(fā)一次


然后看看vue的官方文檔里面提到的使用lodash庫(kù)來(lái)實(shí)現(xiàn)防抖的儒拂。vue在watch時(shí)使用防抖

<!-- 提供這些功能以保持精簡(jiǎn)。這也可以讓你自由選擇自己更熟悉的工具色鸳。 -->
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 發(fā)生改變社痛,這個(gè)函數(shù)就會(huì)運(yùn)行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce` 是一個(gè)通過(guò) Lodash 限制操作頻率的函數(shù)。
    // `_.debounce` 函數(shù) (及其近親 `_.throttle`) 的知識(shí)命雀,
    // 請(qǐng)參考:https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      //do something...
    }
  }
})
</script>

可以發(fā)現(xiàn)有了lodash這個(gè)JavaScript庫(kù)之后蒜哀,要寫(xiě)節(jié)流可防抖是非常方便的。
然后看看lodash里面關(guān)于防抖debounce節(jié)流throttle的相關(guān)介紹吧咏雌。

防抖debounce

_.debounce(func, [wait=0], [options={}])

debounce的參數(shù)
func (Function): 要防抖動(dòng)的函數(shù)。
[wait=0] (number): 需要延遲的毫秒數(shù)校焦。
[options={}] (Object): 選項(xiàng)對(duì)象赊抖。
[options.leading=false] (boolean): 指定在延遲開(kāi)始前調(diào)用。
[options.maxWait] (number): 設(shè)置 func 允許被延遲的最大值寨典。
[options.trailing=true] (boolean): 指定在延遲結(jié)束后調(diào)用氛雪。

// 避免窗口在變動(dòng)時(shí)出現(xiàn)昂貴的計(jì)算開(kāi)銷(xiāo)。
jQuery(window).on('resize', _.debounce(calculateLayout, 150));

節(jié)流throttle

_.throttle(func, [wait=0], [options={}])

throttle的參數(shù)
func (Function): 要節(jié)流的函數(shù)耸成。
[wait=0] (number): 需要節(jié)流的毫秒报亩。
[options={}] (Object): 選項(xiàng)對(duì)象浴鸿。
[options.leading=true] (boolean): 指定調(diào)用在節(jié)流開(kāi)始前。
[options.trailing=true] (boolean): 指定調(diào)用在節(jié)流結(jié)束后弦追。

// 避免在滾動(dòng)時(shí)過(guò)分的更新定位
jQuery(window).on('scroll', _.throttle(updatePosition, 100));

我大概看了一下lodash的官方文檔岳链,很豐富耶,感覺(jué)如果用這個(gè)js庫(kù)的話可以省事又規(guī)范劲件,找時(shí)間看一哈掸哑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市零远,隨后出現(xiàn)的幾起案子苗分,更是在濱河造成了極大的恐慌,老刑警劉巖牵辣,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摔癣,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡纬向,警方通過(guò)查閱死者的電腦和手機(jī)择浊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罢猪,“玉大人近她,你說(shuō)我怎么就攤上這事∩排粒” “怎么了粘捎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)危彩。 經(jīng)常有香客問(wèn)我攒磨,道長(zhǎng),這世上最難降的妖魔是什么汤徽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任娩缰,我火速辦了婚禮,結(jié)果婚禮上谒府,老公的妹妹穿的比我還像新娘拼坎。我一直安慰自己,他們只是感情好完疫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布泰鸡。 她就那樣靜靜地躺著,像睡著了一般壳鹤。 火紅的嫁衣襯著肌膚如雪盛龄。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音余舶,去河邊找鬼啊鸭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛匿值,可吹牛的內(nèi)容都是我干的赠制。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼千扔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼憎妙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起曲楚,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤厘唾,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后龙誊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體抚垃,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年趟大,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹤树。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逊朽,死狀恐怖罕伯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叽讳,我是刑警寧澤追他,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站岛蚤,受9級(jí)特大地震影響邑狸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涤妒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一单雾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧她紫,春花似錦硅堆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至围详,卻和暖如春朴乖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背助赞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工买羞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雹食。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓畜普,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親群叶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吃挑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355