我正在浏览这个博客并阅读有关 Observables 的内容,但无法弄清楚 Observable 和 Subject 之间的区别。
rxjs 中的 Observable 和 Subject 有什么区别?
在流编程中有两个主要接口:Observable和Observer。
Observable是针对消费者的,它可以被转化和订阅:
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
Observer是用于提供可观察源的接口:
observer.next(newItem)
我们可以使用Observer创建新的Observable:
var observable = Observable.create(observer => {
observer.next('first');
observer.next('second');
...
});
observable.map(x => ...).filter(x => ...).subscribe(x => ...)
或者,我们可以使用一个主题,它实现两个可观察和观察接口:
var source = new Subject();
source.map(x => ...).filter(x => ...).subscribe(x => ...)
source.next('first')
source.next('second')
Observables 设计为单播,Subjects 设计为多播。
如果您查看下面的示例 -每个订阅都会收到不同的值作为设计为单播开发的 observable。
import {Observable} from 'rxjs';
let obs = Observable.create(observer=>{
observer.next(Math.random());
})
obs.subscribe(res=>{
console.log('subscription a :', res); //subscription a :0.2859800202682865
});
obs.subscribe(res=>{
console.log('subscription b :', res); //subscription b :0.694302021731573
});
如果您期望订阅的值相同,这可能会很奇怪。
我们可以使用 Subjects 来解决这个问题。主题类似于事件发射器,它不会为每个订阅调用。考虑下面的例子。
import {Subject} from 'rxjs';
let obs = new Subject();
obs.subscribe(res=>{
console.log('subscription a :', res); // subscription a : 0.91767565496093
});
obs.subscribe(res=>{
console.log('subscription b :', res);// subscription b : 0.91767565496093
});
obs.next(Math.random());
两个订阅都获得了相同的输出值!。
可观察对象
他们很冷漠:当他们至少有一个观察者时,代码就会被执行。
创建数据副本:Observable 为每个观察者创建数据副本。
单向:Observer 不能为 observable(origin/master)赋值。
代码将为每个观察者运行。如果是 HTTP 调用,则每个观察者都会调用它。
如果它是我们想要在所有组件之间共享的服务,它不会有最新的结果所有新订阅者仍将订阅相同的可观察对象并从头开始获取value
单播意味着可以从 observable 而不是任何其他组件发出值。
主题
它们很热:即使没有观察者,代码也会被执行并且值会被广播。
共享数据:在所有观察者之间共享相同的数据。
双向:Observer 可以为 observable(origin/master) 赋值。
如果使用 using 主题,那么您将错过在创建观察者之前广播的所有值。所以这里来了重播主题
多播,可以将值投射到多个订阅者,并且可以同时充当订阅者和发射者
请参阅 rxjs 文档(更多信息和示例):http ://reactivex.io/rxjs/manual/overview.html#subject
什么是主题?RxJS Subject 是一种特殊类型的 Observable,它允许将值多播到许多观察者。普通的 Observable 是单播的(每个订阅的 Observer 拥有一个独立的 Observable 执行),而主题是多播的。
一个 Subject 就像一个 Observable,但可以多播给许多观察者。主题就像 EventEmitters:它们维护着许多侦听器的注册表。
和代码,Subject
扩展Observable
:https : //github.com/ReactiveX/rxjs/blob/master/src/internal/Subject.ts#L22
/**
* @class Subject<T>
*/
export class Subject<T> extends Observable<T> implements SubscriptionLike {
//...
}
我发现接受的答案有点令人困惑!
一个观察员 不用于喂养的接口可观察源,它是接口观察的可观察源...这使得从名字更有意义吧?
所以,原因是:
var observable = Observable.create(observer => {
observer.next('first');
observer.next('second');
...
});
工作 - 创建一个发出“第一个”然后“第二个”的 observable - 的参数Observable.create(...)
是subscribe 函数,它基本上定义了哪些Observer事件将在该Observable的直接Observer上发生。
如果你想再深入一点,重要的是要理解订阅函数在你订阅时不是直接在Observer对象上调用的,而是由一个Subscription对象中介,它可以强制执行正确的可观察规则,例如一个可观察绝不会发出一个新的值之后observer.complete()
被调用,即使你的订阅功能,看起来好像会。
参考:http : //reactivex.io/rxjs/manual/overview.html#creating-observables
一个Subject既是一个Observable又是一个观察者,再一次,它看起来就像Observer接口是将事件“馈送”给Subject 的方式。但是,如果您意识到Subject有点像Observable并具有与 subscribe 功能等效的Observable(即您定义观察它的事物将发生什么事件的地方),则它更容易理解命名坐在对象上,即使在它之后已经被创造了。所以,你在Subject上调用Observer方法来定义什么Observer事件会发生在观察它的事物上!😊(同样,涉及中间对象,以确保您只能做合法的事情序列。)