iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
自我挑戰組

菜雞也能優雅的征服RxJS系列 第 22

菜雞們一起征服RxJS - day22 - 別急~先讓子彈飛一會兒: debounceTime

  • 分享至 

  • xImage
  •  

  • 讓子彈飛這部經典電影有一句台詞,先讓子彈飛一會兒,意思是,不要急著去看結果,你給他點時間,他會給你個交代。
  • 今天要介紹的debounceTime就像是這樣的道理,趕緊來看看!

debounceTime


圖片來源 RxJS官網- debounceTime

  • 單看RxJS官網的圖可能還是不知其所以然,因此,我在底部加上了時間的部分來做了說明:
  1. debounceTime(20): 代表當資料發出後的20ms內,都沒有任何資料過來,我就pass
  2. 標示綠色的代表符合條件,因此a, c, d都被選入
  3. 標示紅色代表不符合條件,20ms內都有其他資料發出,因此不被選入

case1

  • 我們先來個簡單的例子,熟悉一下debounce,需求如下:
  1. 建立一個偵測滑鼠點擊事件:fromEvent
  2. 使用者點在1000ms時間內點擊無效,直到他停止點擊,我才會將最後一個點擊的結果給他。

stackblitz

import { fromEvent, debounceTime } from 'rxjs';

// case: click event + debounceTime
fromEvent(document, 'click').pipe(debounceTime(1000)).subscribe(console.log);

  • 透過例子我們嘗試著點擊頁面,然後靜止一段時間,debounceTime順勢傳遞資料。
  • 對照著彈珠圖來看,就能輕鬆理解debounceTime的使用方式囉!☕

case2:

需求如下:

  1. 建立一個inputHTML
  2. 偵測使用者於input輸入資料的時間,是1000ms: debounceTime
  3. 使用者在input輸入一樣的資料,就不傳遞: distinctUntilChanged

stackblitz

  • HTML:
  <input id="input-field" />
    <div>
      <span>You Type:</span>
      <span id="msg"></span>
    </div>
  • JS:
import { fromEvent, debounceTime, map, distinctUntilChanged } from 'rxjs';

// case2: keyup event + debounceTime
const inputField = document.getElementById('input-field');
const msg = document.getElementById('msg');
fromEvent(inputField, 'keyup')
  .pipe(
    debounceTime(1000), // debounceTime
    map((event: KeyboardEvent) => event.target.value), // 取輸入的值
    distinctUntilChanged() //<-- 判斷是否重複輸入
  )
  .subscribe((val) => {
    msg.innerHTML = `${val}`;
  });

解析

  1. 當使用者輸入123並停個一秒,由於是第一筆資料,故資料送出。
  2. 使用者在一秒鐘之內,輸入4,5又反悔刪掉,故資料與上一筆一樣,被distinctUntilChanged過濾掉
  3. 之後輸入4,5,等待個一秒,就被接受啦!
  4. 依此類推

思考看看☕

  • 下面這題各位可以思考看看,他會印出什麼呢??
import { from, debounceTime } from 'rxjs';
from([1, 2, 3, 4, 5]).pipe(debounceTime(1000)).subscribe(console.log);

✍Recap

  1. debounceTime(Nms):捨棄過去的任何資料,僅保留最後一筆且停留N millisecond的資料。
  2. 上方的彈珠圖可以幫助我們理解這樣的觀念。
  3. debounceTimedistinctUntilChanged(參考day21連結)可以更優化使用者體驗,避免短時間內重複發送事件資料或呼叫API,導致系統效能下降。
  4. 補充: debounceTime(1000)也可與debounce(interval(1000))有一樣的效果喔!

完成第22天,這兩天周末,與好友挑戰了台南的山區,共完成了約175公里的路程,覺得自己又更清楚目標在哪裡,加油,繼續往更好的自己邁進~ GO。


上一篇
菜雞們一起征服RxJS - day21: 蒐集不重複的資料 distinctUntilChanged及distinctUntilKeyChanged
下一篇
菜雞們一起征服RxJS - day23: 第一個觸發的就被選中,其他的請離開,直到下一個時間區間來臨 - throttleTime
系列文
菜雞也能優雅的征服RxJS32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言