[RxJS] 認識彈珠圖 Marble Diagram

|

之前的文章我們花了不少篇幅把學習 ReactiveX 前應該具備的知識都建立起來了,接下來就讓我們回歸到 ReactiveX,認識一下 ReactiveX 本身需要知道的知識吧。第一天讓我們學習一下如何閱讀「彈珠圖 Marble Diagram」。

關於彈珠圖 Marble Diagram

由於 ReactiveX 具有 stream 的觀念,加上有大量的 operators 來幫助我們改變 stream 的資料流向,因此如何表達資料的流向就非常重要!在 ReactiveX 中,我們會使用彈珠圖來表達資料流向,因此能夠繪製及閱讀彈珠圖就變成學習 ReactiveX 必備的技術!

如何繪製彈珠圖

接下來我們將實際繪製一個簡單的彈珠圖,除了閱讀文章之外,也歡迎實際拿紙出來畫畫看喔!

畫出資料流

首先,我們需要繪製一條橫線,代表時間軸,時間軸的左邊代表「過去」,右邊帶表「未來」:

在時間軸上,會有各式各樣的「事件」(next())發生,這種事件在圖上都會用一顆「彈珠」來表示,並於彈珠內寫上事件的「值」:

如果這個資料流結束 (complete()) 了,則會在結束的時候標記一個垂直符號 (|):

如果這個資料流有發生錯誤 (error()),則標記一個錯誤符號 (X):

加入 Operator

除了建立類型外的 operators (之後我們再來說明 operators 有哪些類型) 都是將一個 observable (也就是 stream) 換成另一個 observable,在彈珠圖上,我們會在來源資料流下面加上要使用 operator 及使用方法,例如:

上述例子我們用了 map 這個 operator,並將每個流入 operator 的資料「加一」,因此會產生一條新的 observable,在彈珠圖上就可以畫出一條新的時間軸:

如果有多個 operators 呢?就持續補上「使用的 operator」及「新的 observable」就好:

如果相對好理解,當然也可以簡化每次產生新的 observable 的行為,畫出最終結果就好:

很簡單吧!透過彈珠圖,可以把複雜的程式碼簡化成好閱讀的資料流向圖,在溝通和理解也會變得更加簡單喔!

文字版彈珠圖

在白板上畫出彈珠圖是與人溝通資料流向的最佳管道,但有些時候我們無法直接與人面對面畫出彈珠圖來溝通,尤其是遠端工作盛行的現在,或是在撰寫文章/文件時,如果還要用電腦軟體畫出彈珠圖,反而會花費更多時間,所以還有一種版本的彈珠圖,是單純用電腦文字來表示的。文字版彈珠圖的組成要素如下:

  • 使用 - 代表一個時間點單位不拘,方便顯示就好,以下是一條時間軸
-----------------------------------
  • 當有事件發生時,直接在該時間上把 - 取代成發生的資料
-----1-----2-----3-----4-----------
  • 另外,如果有資料是在同一個時間點發生,則可以用小括號包起來
-----(12)--3-----4-----------------

這裡的 (12) 代表 1 和 2 兩個值是在同一個時間點發生的

  • 有時候為了對齊方便,會直接用空白 來當作沒任何事情,也沒有任何時間概念 (純粹對齊用)
-----(12)--3-----4-------
----- a  --b-----c-------
     ^ 這邊 (12) 和 a 代表同樣時間點

在資料是同步的時候,不會加上單位時間的符號 -,也可以使用空白符號方便內容對齊,閱讀上也會更方便

(1      2      3      4      |)
(a      b      c      d      |)

上面兩個資料流都是同步發生的,但為了讓畫面更清楚,使用空白符號讓資料不要擠在一起。

  • 當資料流結束,加上 |
-----1-----2-----3-----4-----------|
  • 如果事件發生完立刻結束呢?一樣用小括號把資料含結束符號包起來就好
-----1-----2-----3-----(4|)
  • 當發生錯誤時,加上 #
-----1-----2-----3-----4------#----
  • 有 operator 時,一樣在原來時間軸下方寫下 operator 的使用
-----1-----2-----3-----4-----------|
map(x => x + 1)
  • 然後畫出新的時間軸 (observable)
-----1-----2-----3-----4-----------|
map(x => x + 1)
-----2-----3-----4-----5-----------|
  • 有多個 operators 時,一樣持續加入「使用的 operator」及「新的 observable」
-----1-----2-----3-----4-----------|
map(x => x + 1)
-----2-----3-----4-----5-----------|
filter(x => x % 2 === 0)
-----2-----------4-----------------|
  • 或簡單加上最後結果
-----1-----2-----3-----4-----------|
map(x => x + 1)
filter(x => x % 2 === 0)
-----2-----------4-----------------|

很簡單吧!在使用文字版彈珠圖時,建議一律使用等寬字體(如 Consolas 等),在排版上會方便許多!使用 markdown 時,程式碼區塊基本上都是等寬字體,所以處理起來真的很方便哩。

這種文字彈珠圖的表示方式會是未來我們介紹 operators 時主要的說明方式,比較複雜的情境才會考慮畫圖處理;而在之後介紹 RxJS 測試時也會用到(測試時會有更多符號)。

本日小結

今天我們介紹了彈珠圖的繪製方式,在未來介紹各種多采多姿的 operators 時會大量的使用到,建議可以多看幾遍,也自己嘗試繪製看看。

明天開始我們會介紹一些基本建立 observable 的方法,在之前我們都是使用 Subject 來建立,實際上還有幾種方法基礎的建立方法,各自有不同的應用情境,今天就先休息一下,明天繼續吧!

如果您覺得我的文章有幫助,歡迎免費成為 LikeCoin 會員,幫我的文章拍手 5 次表示支持!
[RxJS] Functional Programming 常用基本技巧及應用
[RxJS] 建立 Observable 的基礎 - Observable / Subject / BehaviorSubject / ReplaySubject / AsyncSubject

有任何問題或建議嗎?歡迎留言給我