# RxJS講義
RxJS為一種資料串流為基礎,宣告式的程式設計方式,以ReactiveX概念的JavaScript實作。ReactiveX一系列基於可觀察的資料流API適合操作非同步程式設計,結合***觀察、迭代、函式***等主要的設計概念。
## 資料V.S. 資料串流(streaming)
資料為單向筆資訊取得,資料串流唯一連串的資料及運串結果,且隨著時間觀念而不段變化,補充說明:(時間來的不固定,資料回/傳完畢,client端自動斷線)。
舉例情境:影片串流(進影音平台讓每個人同等頻寬,可同時服務的人更多。)、直播、續傳軟體(續傳的行為可以說串流資料)、股票即時資訊(金融類相關資訊)、線上遊戲(LOL),資料舉例:圖檔。
Q:假如同時抓20個工單,一個工單有10件商品,總共200個商品,client端要處理大量處理,發出220 http request/response,所有資料取回得到畫面上,這樣的行為是串流嗎?一口氣request到伺服器,20發出去,回來必須依序回來,會怎麼操作?
A:非同步的這種操作,就可以利用RxJS來處理及組合資料串流的相關問題。
### 命令式(Imperative)
強調執行實作細節,傳統的FOR迴圈
### 宣告式(declarative)
強調執行的過程與目標,可讀性較高,RxJS就是宣告式方式寫法。
JavaScript非同步程式設計,會將程式碼工作放在等待區,等執行完畢後,再決定是否繼續非同步的程式碼。
舉例API:DOM(CLICK、CHANGE、INPUT、SUBMIT),遠端伺服器抓取資料用(XMLHttpRequest、 fetch),Timers(setTimeout、setInterval)
**結論**
非同步程式碼放置等待區,不會因等待而造成畫面阻塞(non-blocking I/O)
執行順需不一定依序由上而下,如何處理接收非同步成一大重點
當非同步行為越來越多,如何整合成為新議題。
## 觀察者模式Observer Pattern
偵測資料變更的責任反轉。
* 觀察者(observer)
notify當目標資料變更,由目標主動呼叫觀察者的notify方法,告知資料變更了。
* 目標(subject)
* notifyObservers,用來通知所有目前的觀察者資料變更,也就是呼叫所有觀察者的notify方法
* addObserver,將某個物件加入觀察者清單
* deleteObserver,將某個物件從觀察者清單移除
## 迭代模式Iterator Pattern
使用for迴圈走訪所有元素,樹狀結構的資料,使用遞迴走訪所有樹狀資料。
使用迭代器模式hasNext(),next(),就能達成以上這些狀態。
## 函式程式設計Functional Programming
OOP物件導向(Angular)、FP函數式(RxJS),兩種混搭的方式。
* 函式最基本的運算單位,避免使用程式狀態及可變物件
* 程式狀態
當函式觀點來看,狀態可分內部狀態(函式內),外部狀態(函式外),若內部改變外部物件,這樣就不太妥當,會無法預測改變原本的值。
純函式Pure Function,相同輸入值的運算結果得到一樣的輸出值,函式內不無任何函式副作用(side effect)操作。函式副作用舉例:HTTP呼叫、檔案存取I/o、DOM操作、console.log。
* 可變物件(mutable object)
JavaScript都是可變物件,原始型別不具可變性(immutable),最常使用ES6展開運算式(Spread syntax)語法,物件型別具有可變形(mutable)。
以Angular為例,進行變更偵測時,預設會使用髒檢查(dirty check),深入物件每個屬性比較是否有資料變更,檢查成本較為龐大,如何避免?就是使用Pure Function。
* λ運算式(函式本身可不具名匿名函式,λ運算式可接受函式當作輸入(引數)輸出(傳出值)
## 函式程式設計技巧
### 組合(compose)
可讓一系列清單依照先後順序執行,避免巢狀方式,讓每個韓式的輸出值皆為下一個輸入值,閱讀順序符合一般數學運算。
### 管線(pipe)與組合相似
但將執行順序反過來,符合一般程式設計師對於程式碼閱讀由上到下的習慣
Tap function,傳入一個函式fn做為參數,包含data參數的內部函式,執行fn(data),呼叫完畢後直接回傳參數。
* 強調執行結果
* 高階函式(Higher-order function)是一個函式,至少符合以下條件:傳入一個或多個函式物件,必須回傳一個函式物件。不用去管低階函式如何實作,直接回傳另一個函式。像是柯里化(currying)
## Functional Programming結論
優點,適度抽象畫,拆多個函式,重用性更高
缺點,過度抽象畫,造成閱讀困難,多運算邏輯拆開,效能較低
設計建議,多撰寫純函式,宣告式思考,善用高階函式,柯理化,將實作細節委外,提高函式共用性,結合組合及管線運用,寫出更加宣告式的程式碼。
## RxJS核心角色
Observable可被觀察的物件,Observer觀察者,Subscription訂閱物件,缺一不可。Operators運算子,Subject觀察目標,Scheduler排程控制器,對主要三大項進行操作處理。
進行步驟:建立Observable,組合Observable,監聽Observable
### 彈珠圖Marble Diagram
參考官方文件
* [rxjs](https://rxjs.dev/)
* [rxmarbles](https://rxmarbles.com/)

## Observable 基礎
在RxJS最基本建立資料流的方法
* Observable類別
* Subject類別
* BehaviorSubject類別
* AsyncSubject類別
## RxJS運算子
Operators種類
## 資料來源
* [rxjs](https://rxjs.dev/operator-decision-tree)
* [完整API](https://rxjs.dev/api?type=function)
## 可觀察物件的簡易分類Cold Observable v.s. Hot Observable
* Cold Observable
當有訂閱發生,才啟動資料流,每次執行會得到一樣的資料流程,每個訂閱彼此獨立
* Hot Observable
當Observable建立當下運作中的資料流,新事件產生時,會推送當下訂閱的觀察者,目標都是同一份運作
###### tags: `Angular` `RxJS`