[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
來建立,實際上還有幾種方法基礎的建立方法,各自有不同的應用情境,今天就先休息一下,明天繼續吧!