手寫Debounce 防抖函數(shù)遇到的坑

最開始寫的防抖函數(shù)

  function debounce(fn, delay) {
    let timer;
    // 返回一個(gè)函數(shù),這個(gè)函數(shù)會(huì)在一個(gè)時(shí)間區(qū)間結(jié)束后的 delay 毫秒時(shí)執(zhí)行 fn 函數(shù)
    return function () {
      // 保存函數(shù)調(diào)用時(shí)的上下文和參數(shù)尘奏,傳遞給 fn
      let context = this
      let args = arguments
      // 每次這個(gè)返回的函數(shù)被調(diào)用纯续,就清除定時(shí)器魏蔗,以保證不執(zhí)行 fn
      clearTimeout(timer)
      // 當(dāng)返回的函數(shù)被最后一次調(diào)用后(也就是用戶停止了某個(gè)連續(xù)的操作)澈魄,
      // 再過 delay 毫秒就執(zhí)行 fn
      timer = setTimeout(function () {
        fn.apply(context, args)
      }, delay)
    }
  }

寫兩個(gè)按鈕來執(zhí)行

<input type="button" value="觸發(fā)按鈕" onclick="btnclick()"/>
<input id="btn" type="button" value="監(jiān)聽按鈕"/>

這里 問題就來了 比如點(diǎn)擊兩次 這樣做的話就會(huì)出現(xiàn) 2秒之后 打印2次console

  function btnclick() {
    debounce(function () {
      console.log('觸發(fā)按鈕的點(diǎn)擊事件')
    }, 1000)()
  }

但是下面這樣寫就是正確的 連續(xù)點(diǎn)擊兩次 最后一次點(diǎn)擊兩秒之后打印console

  let btn = document.getElementById('btn')
  btn.addEventListener('click', debounce(() => {
    console.log('監(jiān)聽按鈕')
  }, 1000))

這里困惑了很久才發(fā)現(xiàn) 實(shí)際上事件監(jiān)聽相當(dāng)于是吧debounce函數(shù)的返回值先拿到 再在點(diǎn)擊的時(shí)候執(zhí)行這個(gè)返回函數(shù)

而觸發(fā)按鈕是每次點(diǎn)擊都會(huì)執(zhí)行debounce這個(gè)函數(shù) 執(zhí)行debouce就會(huì)初始化 let timer 下面的clearTimeout就沒有辦法清除定時(shí)器

解決辦法: 直接把這個(gè)timer給this 每次執(zhí)行的時(shí)候都不會(huì)初始化timer
當(dāng)然 比較笨的辦法就是先把debouce函數(shù)的返回函數(shù)緩存下來 點(diǎn)擊的時(shí)候才執(zhí)行

let d = debounce(function () {
console.log('事件函數(shù)')
}, 1000)

function btnclick() {
d()
}

  function debounce(fn, delay) {
    // 返回一個(gè)函數(shù)厢蒜,這個(gè)函數(shù)會(huì)在一個(gè)時(shí)間區(qū)間結(jié)束后的 delay 毫秒時(shí)執(zhí)行 fn 函數(shù)
    return function () {
      // 保存函數(shù)調(diào)用時(shí)的上下文和參數(shù)轻纪,傳遞給 fn
      let context = this
      let args = arguments
      // 每次這個(gè)返回的函數(shù)被調(diào)用齿梁,就清除定時(shí)器催植,以保證不執(zhí)行 fn
      clearTimeout(this.timer)
      // 當(dāng)返回的函數(shù)被最后一次調(diào)用后(也就是用戶停止了某個(gè)連續(xù)的操作),
      // 再過 delay 毫秒就執(zhí)行 fn
      this.timer = setTimeout(function () {
        fn.apply(context, args)
      }, delay)
    }
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勺择,一起剝皮案震驚了整個(gè)濱河市创南,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌省核,老刑警劉巖稿辙,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異气忠,居然都是意外死亡邻储,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門旧噪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吨娜,“玉大人,你說我怎么就攤上這事舌菜∶瓤牵” “怎么了亦镶?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵日月,是天一觀的道長袱瓮。 經(jīng)常有香客問我,道長爱咬,這世上最難降的妖魔是什么尺借? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮精拟,結(jié)果婚禮上燎斩,老公的妹妹穿的比我還像新娘。我一直安慰自己蜂绎,他們只是感情好栅表,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著师枣,像睡著了一般怪瓶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上践美,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天洗贰,我揣著相機(jī)與錄音,去河邊找鬼陨倡。 笑死敛滋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兴革。 我是一名探鬼主播绎晃,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杂曲!你這毒婦竟也來了箕昭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤解阅,失蹤者是張志新(化名)和其女友劉穎落竹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體货抄,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡述召,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蟹地。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片积暖。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖怪与,靈堂內(nèi)的尸體忽然破棺而出夺刑,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布遍愿,位于F島的核電站存淫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沼填。R本人自食惡果不足惜桅咆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坞笙。 院中可真熱鬧岩饼,春花似錦、人聲如沸薛夜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梯澜。三九已至硕糊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腊徙,已是汗流浹背简十。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撬腾,地道東北人螟蝙。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像民傻,于是被迫代替她去往敵國和親胰默。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

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

  • 1漓踢、使用typeof bar ===“object”來確定bar是否是一個(gè)對(duì)象時(shí)有什么潛在的缺陷牵署?這個(gè)陷阱如何避免...
    我是大橙閱讀 579評(píng)論 0 1
  • 1、使用typeof bar ===“object”來確定bar是否是一個(gè)對(duì)象時(shí)有什么潛在的缺陷喧半?這個(gè)陷阱如何避免...
    深海鯽魚堡閱讀 662評(píng)論 1 1
  • 一奴迅、Python簡介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡介】: Python 是一個(gè)...
    _小老虎_閱讀 5,748評(píng)論 0 10
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • 長久以來挺据,面向?qū)ο笤?JavaScript 編程范式中占據(jù)著主導(dǎo)地位取具。不過,最近人們對(duì)函數(shù)式編程的興趣正在增長扁耐。函...
    神刀閱讀 469評(píng)論 0 0