1

根据Subject 上的文档,这是Observable的一个特例,它让所有的观察者共享一个共同的执行路径。该示例显示每个观察者在订阅源后都会获得相同的发出值。

我并不完全清楚它与计划Observable发射值的情况有何不同。多个订阅者中的每一个都将收到每个next 'ed 值。在相应订阅之前发出的值不会被传递(除非我们在某些shareReply中明确地使用管道)。

使Subject成为Observable的特例的实际区别是什么?我错过了明显的,可能。

4

3 回答 3

5

根据定义,可观察对象是数据生产者。

另一方面,主题可以同时充当数据生产者和数据消费者。

这意味着两件事。

  1. 可以订阅主题,就像 observable 一样。
  2. 主题可以订阅其他可观察对象。

话虽如此,主题和可观察对象之间存在一个关键区别。

一个主题的所有订阅者共享该主题的相同执行。即当一个主体产生数据时,它的所有订阅者都将收到相同的数据。这种行为与可观察对象不同,其中每个订阅都会导致可观察对象的独立执行。

例子:

  // Here a subject is acting like a data producer
  const subject = new Subject();
  const subjObserv = subject.asObservable();
  subjObserv.subscribe((data: number) => console.log("subect A " + data));

  for (let i = 1; i <= 5; i++) subject.next(i);

  subjObserv.subscribe((data: number) => console.log("subect B " + data));
  subject.next(6);


  // simple observer
  const plainObs = Observable.of([1, 2, 3, 4, 5]);
  plainObs.subscribe(data => console.log("plain onservable A " + data));
  plainObs.subscribe(data => console.log("plain onservable B " + data));

输出:

subect A 1
subect A 2
subect A 3
subect A 4
subect A 5
subect A 6
subect B 6
plain onservable A 1,2,3,4,5
plain onservable B 1,2,3,4,5

正如您所注意到的,我们获得的输出次数与我们订阅的次数一样多,plainObs但是对于subjObserv我们获得的输出是在订阅后发出的。

于 2020-03-02T05:00:55.130 回答
1

“...让所有的观察者共享一个共同的执行路径”:看看这个

我理解 Observable 和 Subject 之间区别的方式是您可以将.next()值放入 Subject 中,但您不能使用 Observable 来做到这一点。

于 2020-03-02T04:58:55.527 回答
0

这就是我们使用 Subject 的方式,使用 subject(.next) 您可以推送新值,如下所示:

  var source = new Subject();
    source.map(x => ...).filter(x => ...).subscribe(x => ...)
    source.next('newValue1')
    source.next('newValue2')

要创建主题,我们不需要任何观察者。

我们可以使用 Observer 创建新的 Observable,如下所示:

var observable = Observable.create(observer => { 
    observer.next('newValue1'); 
    observer.next('newValue2'); 
    ... 
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)

要创建 observable,您至少需要一个观察者,并且它(Observable)只通知观察者。在这里您不能推送新值,它只会读取从源获得的任何响应。

结论:我的意思是 Observable 就像只是读取值,但主题就像读取和写入值。

于 2020-03-02T05:07:35.953 回答