RxJS 系列 – Subject

前言

RxJS 两大概念 Observable 和 Subject. 上一篇介绍了 Observable 这篇继续接受 Subject.

 

参考

RxJS 建立 Observable 的基礎 - Observable / Subject / BehaviorSubject / ReplaySubject / AsyncSubject

 

介绍

Subject 是典型的观察者模式, 它不是 Observable 那样参杂了 Generator Function 概念, 所以比较容易理解.

当我们说 Subject extends Observable 时, 指的是它可以被订阅. 而不是它拥有所有 Observable 的特性哦.

和 Observable 不同的地方

第一个不同是它们发布的方式.

Observable 的发布逻辑是在初始化方法里面通过 subscriber.next 发布的.

Subject 没有初始化方法. 它这个对象自带 .next 方法来实现发布

第二个不同是 multiple subscribe

Observable multiple subscribe 会参数多条独立的 stream. 

Subjust multiple subscribe 则不会产生多条 stream. 每次 subscurbe 它只是把 callback 函数存起来, 发布时挨个调用而已 (典型的观察者模式实现)

 

Subject 创建与订阅

const subject = new Subject();
subject.subscribe({
  next: () => console.log('next'),
  complete: () => console.log('complete'),
});
subject.next('');
subject.complete();

简单明了, 和常见的 addEventListener 一样的逻辑.

 

BehaviorSubject

stream 是一个值一段时间内的变化.

Subject 只是事件发布. 它表达不了 stream 概念. 于是就有了 BehaviorSubject

const bSubject = new BehaviorSubject<string>('init value');
bSubject.subscribe(value => console.log(value)); // 直接触发拿到 init value
console.log(bSubject.value); // 获取当前 value
bSubject.next('new value'); // update value 同时发布给所有 subscriber

有了 BehaviorSubject 它就像一个可被监听的 variable 了.

 

ReplaySubject

ReplaySubject 的作用是把 value cache 起来. 当订阅的时候可以直接获取所有 cached values

const rSubject = new ReplaySubject<string>(1); // cache 1 个值, 也可以 cahce 多个
rSubject.next('first value'); // 输入 init value
rSubject.subscribe(v => console.log(v)); // 立刻拿到 init value
rSubject.next('second value'); // 更新 cached value 同时发布

上面这个例子类似于 BehaviorSubject 的功能. 但 BehaviorSubject 可以 .value 获取当前的 value. ReplaySubject 却不能.

所以它替代不了 BehaviorSubject 哦

 

AsyncSubject

AsyncSubject 我没有用过. 它很特别.

每当 subject.next 的时候它不会发布.

一直到 subject.complete 被调用后, 它才会把最后一个 next value 发布出去 

const aSubject = new AsyncSubject<string>();
aSubject.subscribe({
  next: v => console.log('next', v), // after .complete() this will be call value is 'b'
});
aSubject.next('a');
aSubject.next('b');
aSubject.complete();

 

asObservable

Subject 虽然可以被订阅, 但它也具备发布的功能. 如果我们想让它变成 readonly 只能订阅不能发布可以使用 asObservable

const bSubject = new BehaviorSubject<string>('init value');
const value$ = bSubject.asObservable(); // value$ 只能订阅, 不能发布
value$.subscribe(v => console.log(v));
bSubject.next('next value'); // 发布

 

posted @ 2022-10-01 12:45  兴杰  阅读(340)  评论(0编辑  收藏  举报