原文连接:Understanding rxjs Subjects
原文做者:Luuk Gruijs;发表于2018年4月17日
译者:yk;如需转载,请注明出处,谢谢合做!javascript
RxJS 是真的好用,它能够帮助咱们更好地编辑/订阅数据流。虽然单用 Observable(可观察对象)就能够作不少事情,但 RxJS 仍是提供了多种用于操控数据流的类,Subject(主题)就是其中之一。java
若是你还不知道 Observable 是什么的话,建议先读读个人另外一篇文章:Understanding, creating and subscribing to observables in Angular。若是你以为你明白 Observable 是什么意思,那行咱继续!git
摄影:Anvesh Uppunuthula,来自 Unsplashgithub
Subject 就比如 Observable。你能够订阅它,就像你平时订阅 Observable 同样。它也有相似 next()
,error()
以及 complete()
的方法,就像你平时传给 Observable 构造函数的 observer(观察者)同样。api
使用 Subject 主要是为了多播(multicast)。Observable 默认是单播(unicast)的,而单播就意味着:对于每一个订阅者,都只有一个独立的 Observable execution 与之对应。证实以下:app
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 能够在多个订阅者之间共享。dom
译者注:每当咱们调用一次
Observable.subscribe()
时,一个新的 Observable execution 就会被启动。详见 Observable。函数
Subject 也可比做事件发射器(EventEmitter),其中注册了多个事件监听器。 当咱们订阅 Subject 时,它并不会启动一个新的 execution 来传送数据。而是在现有观察者列表中注册一个新的观察者,仅此而已。ui
多播是 Subject 的特性,使用 Subject 便可实现多播,无需任何技巧。下面是一个简单的示例:spa
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 的全部订阅者都会当即收到这个值。
若是你但愿 Observable 的多个订阅者接收到相同的数据,那就用 Subject 来代替 Observable。因为其 Observable execution 能够在多个订阅者之间共享,因此 Subject 将确保每一个订阅者接收到的数据是绝对相等的。另外,Subject 还有几种变体,我将在下一篇文章中详细描述它们之间的区别。
译者注:后面都是一些可有可无的招聘信息,我就不翻译了,除非你真的想去阿姆斯特丹。