Subject(是 Observable 的特例)和 Observable 之间的区别
Difference between Subject (being a special case of Observable) and Observable
根据 the docs on Subject,这是 Observable 的一个特例,它让所有观察者共享一个公共执行路径。该示例显示每个观察者在订阅源后获得相同的发射值。
我不完全清楚它与计划 Observable 发射值的情况有何不同。多个订阅者中的每一个都将收到每个 next 的值。在相应订阅之前发出的值未交付(除非我们在某些 shareReply 中明确地 pipe'ed) .
使 Subject 成为 Observable 的特例的实际区别是什么?我可能错过了显而易见的东西。
“...让所有观察者共享一个共同的执行路径”:检查this out。
我理解 Observable 和 Subject 之间的区别的方式是你可以 .next()
值到 Subject 中,但你不能用 Observable 做到这一点。
根据定义,可观察对象是数据生产者。
另一方面,主题可以同时充当数据生产者和数据消费者。
这意味着两件事。
- Subject 可以订阅,就像 Observable 一样。
- 一个主题可以订阅其他可观察对象。
话虽这么说,主题和可观察对象之间存在一个关键区别。
All subscribers to a subject share the same execution of the subject.
i.e. when a subject produces data, all of its subscribers will receive
the same data. This behavior is different from observables, where each
subscription causes an independent execution of the observable.
示例:
// 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
我们获得的输出是在订阅后发出的。
这就是我们使用 Subject 的方式,使用 subject(.next) 您可以推送新值,如下所示:
var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('newValue1')
source.next('newValue2')
创建 Subject 我们不需要任何观察者。
我们可以像下面这样用观察者创建新的 Observable:
var observable = Observable.create(observer => {
observer.next('newValue1');
observer.next('newValue2');
...
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
要创建可观察对象,您至少需要一个观察者,并且它(可观察对象)仅通知 observer.here 您不能推送新值,它只会读取从来源获得的任何响应。
结论:我的意思是 Observable 就像只读取值,而 subject 就像读取和写入值。
根据 the docs on Subject,这是 Observable 的一个特例,它让所有观察者共享一个公共执行路径。该示例显示每个观察者在订阅源后获得相同的发射值。
我不完全清楚它与计划 Observable 发射值的情况有何不同。多个订阅者中的每一个都将收到每个 next 的值。在相应订阅之前发出的值未交付(除非我们在某些 shareReply 中明确地 pipe'ed) .
使 Subject 成为 Observable 的特例的实际区别是什么?我可能错过了显而易见的东西。
“...让所有观察者共享一个共同的执行路径”:检查this out。
我理解 Observable 和 Subject 之间的区别的方式是你可以 .next()
值到 Subject 中,但你不能用 Observable 做到这一点。
根据定义,可观察对象是数据生产者。
另一方面,主题可以同时充当数据生产者和数据消费者。
这意味着两件事。
- Subject 可以订阅,就像 Observable 一样。
- 一个主题可以订阅其他可观察对象。
话虽这么说,主题和可观察对象之间存在一个关键区别。
All subscribers to a subject share the same execution of the subject. i.e. when a subject produces data, all of its subscribers will receive the same data. This behavior is different from observables, where each subscription causes an independent execution of the observable.
示例:
// 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
我们获得的输出是在订阅后发出的。
这就是我们使用 Subject 的方式,使用 subject(.next) 您可以推送新值,如下所示:
var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('newValue1')
source.next('newValue2')
创建 Subject 我们不需要任何观察者。
我们可以像下面这样用观察者创建新的 Observable:
var observable = Observable.create(observer => {
observer.next('newValue1');
observer.next('newValue2');
...
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
要创建可观察对象,您至少需要一个观察者,并且它(可观察对象)仅通知 observer.here 您不能推送新值,它只会读取从来源获得的任何响应。
结论:我的意思是 Observable 就像只读取值,而 subject 就像读取和写入值。