Skip to main content

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 的其中一個變體,它有一個拿到當前值的概念。它保存有最新的值,如果有新的值的時候,就可以在 BehaviorSubjectsubscribed 拿到最新的值。

和 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

  1. 擁有初始值,且當外部傳入新的訂閱內容時,會一併修改初始值。
  2. 回播初始值。

ReplaySubject

  1. 擁有紀錄訂閱內容的陣列,並可以設定其紀錄數量,當外部傳入新的訂閱內容時,會放入此陣列。
  2. 回播陣列。
  3. 能夠只取至目前為止一段時間內的訂閱內容。
  4. 即便已經完成(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

online-demo

AsyncSubject

只有當 Observable 執行完成時,它才會執行,把最後一個發送給觀察者

參考文章

https://limeii.github.io/2019/07/rxjs-subject/

https://juejin.cn/post/6861514628132765710

希望是最淺顯易懂的 RxJS 教學

learn rxjs