puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

4 Subject RxJS #184

Open puddlejumper26 opened 3 years ago

puddlejumper26 commented 3 years ago

在 RxJS 中有四种 Subject 分别是:SubjectBehaviorSubjectAsyncSubjectReplaySubject;这四种 Subject 都是特殊的 Observable

image

数据生产者 vs 数据消费者

举个例子,中央电视台每晚7点播送新闻联播。小明7点准时打开电视机开始收看新闻,而小红7点15分才打开电视机,打开电视机相当于一个订阅subscribe的动作,那么小红看到的新闻必然是从第15分钟开始的,在这之后小明小红收看的新闻(数据)是一样的。转换为代码,如果我们使用普通的Observable去实现,那么所有人不管何时打开电视,看到的都会是7点开始的新闻(类似录像),就失去了一个同步性和实时性。这个时候我们就可以用Subject来实现。

// messageService.ts
private shareData: Subject<string> = new Subject<string>();

sendData(value: string) {
    this.shareData.next(value);             <========  数据生产者 (可观察对象, Observable)
}
getData(): Observable<string> {
    return this.shareData.asObservable();           <=========数据消费者(Observer)
}
// B Component
// send data from B Component
  this.messageService.sendData("this message from subject b");
// C Component
// get data in C Component
this.subscription = this.messageService.getData()
    .subscribe(val => {
        this.message = val;
        console.log(val);
    });

在这两个 components 中通过定义在 messageService 的 Subject 共享数据,通过 next() 方法使得 Subject 是数据生产者(可观察对象),通过 asObservable() 使得 Subject 是数据消费者(Observers)。

单播 vs 多播

在上面的代码例子中,不仅是在 component c 可以订阅拿到数据,在其他 component 中也可以订阅拿到数据。比如在 A Component 中定义如下代码:

// A Component
// get data in A Component
this.subscription = this.messageService.getData()
    .subscribe(val => {
        console.log("this is in componet A and " + val);
    })

从 B Component 发出值,在 C Component 和 A Component 能拿到同样的值,这个就是多播

Source