# W_Rxjs note
- rxjs 是用來處理非同步而產生的工具
- 彈珠圖,資料流在運行 Operators 的圖像化
- observable 為觀察對象,它還沒有作用,直到 subscribe 訂閱才會處理值
- pipe() 只是加工 observable,最後還是要對它進行訂閱
## 觀念
### 串流
- 資料流,是一個動詞,在資料還未發送完畢時,會一直輸出,就是資料流,不斷運行者,但還未顯示直到訂閱
- 訂閱就是開啟資料流,讓資料流出,並且可以獲取資料顯示
- 取消訂閱就是把資料流關閉,不論是資料在何種狀態,立即中止
### pipe 為甚麼不能直接接 subscribe ?
設計思維,因為 pipe 做完還有機會重用邏輯。如果後面直接接續訂閱,那此 observable 邏輯就不能重用。除非是已經確定這個 observable 只用在單一事件情況下,便可直接用 subscribe
### 疑問與未解之謎
- Observable of Observable ?
- 如何判斷回傳的是 Observable ?
- 可以用 Map 系列或是 All 系列來自動訂閱,避免巢狀結構 ?
- cold hot observable
## flattening operator
aka 展開運算符,可以講回傳為 Observable 的值展開取的內部的值
flattening 三兄弟
| 目的 | 用法 |
| ------- | ------------- |
| 只要最新的 | `switchAll()` |
| 要全部平行執行 | `mergeAll()` |
| 要依序執行 | `concatAll()` |
## Observable vs Subject
- 兩者都有相同之處
### Observable (一對一,靜態)
- 建立物件同時就決定資料流向
- 每個訂閱者都會得到獨立資料流,又稱單播
### Subject (一對多,動態的)
- 在產生物件後才決定資料流向
- 每次事件發生時,就會同步傳遞給所有訂閱者,稱為多播
- 每次都直接執行資料流
## Observable
他是
## Operator 有分兩種
Creation Operators vs Pipeable Operators
- creation 是用來建立新的 observable,不必透過 new Observable 建立
- pipeable 是將 observable 加工的 operator,必須透過 pipe() 來包裝加工方法
## Operator 運算子
像 js 方法,其中有一些類似 array。專們給 observable 加工的方法
### tap
- 處理 side effect
### subject
-
### debunceTime
- 遏止使用這過度使用按鈕的機制
```javascript!
//這是練習建立 「輸入框輸入文字 → 等 500ms → 將文字轉成大寫後印出」的 RxJS 程式。
import { fromEvent, Observable } from 'rxjs';
import { map, debounceTime } from 'rxjs/operators';
// const div = document.createElement('div');
// div.textContent = 'this just test';
// document.body.appendChild(div);
// div.style.background = 'orange';
// div.style.marginTop = '20px';
//在 document 建立 input
const input = document.createElement('input');
document.body.appendChild(input);
//在 js 操作 html、css
input.placeholder = 'test for nothing';
input.style.padding = '5px';
input.style.borderRadius = '6px';
//建立 rxjs 事件
const input$ = fromEvent(input, 'input');
//建立事件串流,但還沒有使用
const action$ = input$.pipe(
debounceTime(500),
map((e) => e.target.value.toUpperCase())
);
//訂閱事件 開啟串流
action$.subscribe((data) => {
console.log(data);
});
```
### of
- 把資料一個個送出
### from
- 跟 of 有點像,差別是他會列出陣列與物件內容,而 of 是把之料直接傳出,並非一個個釋出
## Subscribe 訂閱
只要使用他就是開啟資料流,開啟訂閱,即便是用變數包裝,它也是開啟狀態
```javascript!
const subscription = timeInterval$.subscribe((data) => {
console.log(`時間會持續輸出偶數: ${data}`);
});
```
### unsubscribe()
它是 subscribe 的方法,我在實作時發現我用 observable$ 來使用 unsubscribe() 所以導致錯誤。
```javascript!
setTimeout(() => {
subscription.unsubscribe(); // ✅ 取消訂閱
console.log('已取消訂閱');
}, 10000);
```
### merge
會將時間差的融合
```javascript!
const test1$ = interval(1000).pipe(
tap(data=> console.log(`A${data}`)
)
const test2$ = interval(3000).pipe(
tap(data=> console.log(`B${data}`)
)
const test3$ = interval(5000).pipe(
tap(data=> console.log(`c${data}`)
)
merge(test1$,test2$,test3$).subscribe(data=>{
console.log(data)
})
// A1
// A2
// A3B1
// A4
// A5C1
```
### zip
跟 merge 很相似,不同的是它會同時印出來,所以第一位會等最後一位,依照時間順序
## partition
它會依據我們設定的規則函式拆成兩個 observable
```javascript!
import { of, partition } from 'rxjs';
const shit$ = of(1, 2, 3, 4, 5, 6, 7, 8);
const [a1$, a2$] = partition(shit$, (data) => data % 2 === 0);
a1$.subscribe((data) => console.log(data));
a2$.subscribe((data) => console.log(data));
//2
//4
//6
//8
//1
//3
//5
//7
```