Observable 的用法和區別
Subject
在訂閱之後,在 next 值進去,才會執行到 subscribe 的 function ,之前的調用的 next 不會被執行到
const thomas$ = new Subject()
thomas$.next(1)
thomas$.subscribe((res)=> {
console.log(res)
})
thomas$.next(2)
// output
// 2
BehaviorSubject
建構式為
constructor(_value: T)
是 Subject 的其中一個變體,它有一個拿到當前值的概念。它保存有最新的值,如果有新的值的時候,就可以在 BehaviorSubject 的 subscribed 拿到最新的值。
和 subject 來比較的話,BehaviorSubject 它會把之前調用 next 的值都在進到 subscribe 的 function 中,也就是說會提供舊有的訂閱內容,也就是幫 Subject 多了一個回播的功能。
const thomas$ = new BehaviorSubject()
thomas$.next(1)
thomas$.subscribe((res)=> {
console.log(res)
})
thomas$.next(2)
// output
// 1
// 2
ReplaySubject
constructor(bufferSize: number = Number.POSITIVE_INFINITY, windowTime: number = Number.POSITIVE_INFINITY, scheduler?: SchedulerLike)
bufferSize為紀錄數量,預設為無限大,當數值小於 1 時,以 1 取代。windowTime為只取多長時間內(milliseconds)的訂閱內容,預設為無限大,也就是不限制時間,當數值小於 1 時,以 1 取代。scheduler因為本文著重於回播功能,所以此變數先不談。
BehaviorSubject vs ReplaySubject
差別如下
BehaviorSubject
- 擁有初始值,且當外部傳入新的訂閱內容時,會一併修改初始值。
- 回播初始值。
ReplaySubject
- 擁有紀錄訂閱內容的陣列,並可以設定其紀錄數量,當外部傳入新的訂閱內容時,會放入此陣列。
- 回播陣列。
- 能夠只取至目前為止一段時間內的訂閱內容。
- 即便已經完成(
complete),在本身取消訂閱(unsubscribe)前都能夠回播。
兩個行為差不多,但 ReplaySubject 會把之前的訂閱的內容存起來,當再一次訂閱的時候,若超出紀錄數量,則將最舊的移出陣列。
import { fromEvent, scan, ReplaySubject } from 'rxjs';
const thomas$ = new ReplaySubject(2)
console.log('start subscribe')
thomas$.next(1)
thomas$.subscribe((res)=> {
console.log(res)
})
thomas$.next(2)
thomas$.next(3)
thomas$.next(4)
thomas$.next(5)
console.log('again subscribe')
thomas$.subscribe((res)=> {
console.log(res)
})
// output
// start subscribe
// 1
// 2
// 3
// 4
// 5
// again subscribe
// 4
// 5
AsyncSubject
只有當 Observable 執行完成時,它才會執行,把最後一個發送給觀察者
參考文章
https://limeii.github.io/2019/07/rxjs-subject/