[译] 认识 rxjs 中的 Subject

原文连接: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

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 的特性,使用 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 还有几种变体,我将在下一篇文章中详细描述它们之间的区别。

想在阿姆斯特丹找到一份工做吗?

译者注:后面都是一些可有可无的招聘信息,我就不翻译了,除非你真的想去阿姆斯特丹。

相关文章
相关标签/搜索