[译] 认识 rxjs 中的 Subject

原文链接: Understanding rxjs Subjects

原文作者:Luuk Gruijs;发表于2018年4月17日

译者: yk ;如需转载,请注明 出处 ,谢谢合作!

RxJS 是真的好用,它可以帮助我们更好地编辑/订阅数据流。虽然单用 Observable(可观察对象)就可以做很多事情,但 RxJS 还是提供了多种用于操控数据流的类,Subject(主题)就是其中之一。

如果你还不知道 Observable 是什么的话,建议先读读我的另一篇文章: Understanding, creating and subscribing to observables in Angular 。如果你觉得你明白 Observable 是什么意思,那行咱继续!

摄影:Anvesh Uppunuthula,来自Unsplash

Subject

Subject 就好比 Observable。你可以订阅它,就像你平时订阅 Observable 一样。它也有类似 next()error() 以及 complete() 的方法,就像你平时传给 Observable 构造函数的 observer(观察者)一样。

使用 Subject 主要是为了多播(multicast)。Observable 默认是单播(unicast)的,而单播就意味着:对于每个订阅者,都只有一个独立的 Observable execution 与之对应。证明如下:

import * as Rx from "rxjs";

const observable = Rx.Observable.create((observer) => {
  observer.next(Math.random());
});

// 订阅者甲
observable.subscribe((data) => {
  console.log(data); // 0.24957144215097515 (随机数)
});

// 订阅者乙
observable.subscribe((data) => {
  console.log(data); // 0.004617340049055896 (随机数)
});
复制代码

由于 Observable 在设计上就是单播的,所以如果你希望使多个订阅者收到相同的数据,那么用 Observable 可能会非常麻烦。而 Subject 可以帮助我们解决这个问题。正如先前所说,Subject 可以用来实现多播。多播的基本含义是:一个 Observable execution 可以在多个订阅者之间共享。

译者注:每当我们调用一次 Observable.subscribe() 时,一个新的 Observable execution 就会被启动。详见Observable。

Subject 也可比作事件发射器(EventEmitter),其中注册了多个事件监听器。当我们订阅 Subject 时,它并不会启动一个新的 execution 来传送数据。而是在现有观察者列表中注册一个新的观察者,仅此而已。

如何在多播中使用 Subject

多播是 Subject 的特性,使用 Subject 即可实现多播,无需任何技巧。下面是一个简单的示例:

import * as Rx from "rxjs";

const subject = new Rx.Subject();

// 订阅者 1
subject.subscribe((data) => {
  console.log(data); // 0.24957144215097515 (随机数)
});

// 订阅者 2
subject.subscribe((data) => {
  console.log(data); // 0.24957144215097515 (随机数)
});

subject.next(Math.random());
复制代码

奶思!我们使两个订阅者获得了相同的数据。然而,这并非 Subject 的唯一用途。

相比 Observable 只能作为数据的生产者,Subject 即可以作为生产者,也可以作为消费者。通过把 Subject 作为消费者使用,你可以将一个单播 Observable 转换为多播。示例如下:

import * as Rx from "rxjs";

const observable = Rx.Observable.create((observer) => {
  observer.next(Math.random());
});

const subject = new Rx.Subject();

// 订阅者 1
subject.subscribe((data) => {
  console.log(data); // 0.24957144215097515 (随机数)
});

// 订阅者 2
subject.subscribe((data) => {
  console.log(data); // 0.24957144215097515 (随机数)
});

observable.subscribe(subject);
复制代码

将我们的 subject 传递给 subscribe() ,使其接收由 observable 传来的值(消费数据)。随后,subject 的所有订阅者都会立即收到这个值。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章