总结

在总结部分,我们首先回顾下 何时(when) 以及 为什么 使用 Subject。在一些场合下,Subject 是十分必要的,比如某个 Observable 能发出随机数,在同一时刻,我们想要让多个 Observer 看到相同的随机数,我们就可以通过向 multicast 传递 Subject 来 共享 这个 Observable:

const result = Rx.Observable.interval(1000)
  .take(3)
  .do(v => console.log(`source ${v}`))
  .map(v => Math.random())
  .multicast(subjectFactory, function selector(shared) {
    const sharedDelayed = shared.delay(500);
    const merged = shared.merge(sharedDelayed);
    return merged;
  });

如果我们决定使用 Subject,接下来要考虑的是使用哪个类型的 Subject?如果我们需要缓存值,那么就考虑使用 ReplaySubject 或者 BehaviorSubject。

一个 Subject 对象可以理解为只是一个包含了 Observer 列表的 Observable 对象,所以为 Subject 对象订阅一个 Observer 对象也就相当于为该 Subject 对象添加了一个监听器。相对地,订阅一个普通的 Observable 对象,则是直接驱动这个 Observable 的流动。一个 Subject 对象也是一个 Observer,因此,能将 Subject 对象订阅到一个 Observable 对象:

observable.subscribe(subject);
subject.subscribe(observerA);
subject.subscribe(observerB);

概括下来,通过 observable.subscribe(subject),当 observable 有值发出时,这些值会被呈递给 subject。而我们可以通过 subject.subscribe(observer) 添加多个 observer 作为监听器,当值到来时,这些监听器都会获得相应,共享 observable 发出的值。

由于 Subject 具有 Observer 的身份,他也因此具有 nexterrorcomplete的成员方法,我们也因此能通过 Subject 实现 Event Bus 或者说 Event Emitter。但正如之前我们提到的,不要滥用这些 API,否则我们渐渐与响应式程序设计背道而驰。

在使用 Subject 需要万分仔细,例如,当我们手动 connect 一个共享 Observable 后,如果没有正确地结束 Observable 的执行,就有可能造成内存泄露。

如上种种,也许更好的使用 Subject 的方式是,将它隐藏起来,只是利用他的广播特性,而不显示地使用它。RxJS 为我们提供了 publishpublishReplaymulticast 的变种 API 来达到隐藏 Subject,减少使用 Subject 风险的目的。

results matching ""

    No results matching ""