我正在研究Angular RxJs模式,我不明白行为主体和可观察对象之间的区别。

根据我的理解,BehaviorSubject是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与可观察对象的目的完全相同。

什么时候使用可观察对象和行为主体?使用一个行为主体比使用一个可观察对象有好处吗?反之亦然?


当前回答

我认为可观察对象是主体的包装。而Observable仅用于订阅数据更改。Subject还可以用于将数据更改通知订阅者(使用next()方法)。下面是一个小的可观察的模式实现,它可能有助于您理解这个概念。打印稿操场

其他回答

在rxjs中,Subject本质上是一个观察者和可观察对象。观察者是我们放入值的对象,可观察对象是我们可以观察值的对象。

Subject is Hot by default. Observables by default are cold. That means they are not going to emit any values until someone subscribes to it. The instant we create a subject, we can emit a value from it and that value will be emitted even if nobody is subscribed to it yet. Subject is multicast by default. Observable by default are unicast and that means that for every different observer that we have, we have to subscibe to an observable, if that observable emits a value that value is going to flow through all the different operators inside of our pipe once for each subscriber. Multicast means all of other operators will run one time for every value, regardless of the number of observers we have. GOTCHA= thE SUBJECT is multicast but if you chain on a pipe statement to it, that is going to return a new observable that is cold and unicast.

行为主体与主体相同,但也有初始的“种子”值。新订阅用户立即获得最新的值。如果有人订阅了行为主体,它会立即接收到最近的值。所以行为主体总有一些价值可以分给订阅者。

关于行为主体最有用的事情是当我们开始发出网络请求时。想象一下,我们将一些管道连接到一个行为主题上,在一个管道函数或管道操作符中,我们最终发出一个网络请求并获取一些数据。你最终可能会想让其他东西订阅那个可观察对象,并立即获得已经获取的数据。使用行为主体,我们可以很容易地实现这种行为。

我认为可观察对象是主体的包装。而Observable仅用于订阅数据更改。Subject还可以用于将数据更改通知订阅者(使用next()方法)。下面是一个小的可观察的模式实现,它可能有助于您理解这个概念。打印稿操场

把Observables想象成一个管道,里面有流动的水,有时水流动,有时不流动。在某些情况下,你可能真的需要一个一直有水的管道,你可以通过创建一个特殊的管道来做到这一点,不管它有多小,让我们把这个特殊的管道称为行为主题,如果你恰好是你所在社区的供水供应商,你可以安心地睡在晚上,因为你新安装的管道只是工作。

在技术术语中:你可能会遇到一个可观察对象总是有价值的情况,也许你想要捕获输入文本的值,然后你可以创建一个BehaviorSubject的实例来确保这种行为,让我们说:


const firstNameChanges = new BehaviorSubject("<empty>");

// pass value changes.
firstNameChanges.next("Jon");
firstNameChanges.next("Arya");

然后,您可以使用“value”对随时间变化的更改进行抽样。


firstNameChanges.value;

这在你以后组合可观察对象时很方便,通过查看你的流的类型为BehaviorSubject,你可以确保流至少会触发或发出至少一次信号。

Observable对象表示一个基于推的集合。

观察者和可观察接口为基于推送的通知提供了一种通用机制,也称为观察者设计模式。Observable对象表示发送通知的对象(提供者);Observer对象表示接收它们的类(观察者)。

Subject类继承了Observable和Observer,也就是说它既是一个观察者又是一个可观察对象。您可以使用主题订阅所有观察者,然后将主题订阅到后端数据源

var subject = new Rx.Subject();

var subscription = subject.subscribe(
    function (x) { console.log('onNext: ' + x); },
    function (e) { console.log('onError: ' + e.message); },
    function () { console.log('onCompleted'); });

subject.onNext(1);
// => onNext: 1

subject.onNext(2);
// => onNext: 2

subject.onCompleted();
// => onCompleted

subscription.dispose();

更多信息https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/subjects.md

BehaviorSubject是一种类型的主题,主题是一种特殊类型的可观察对象,所以你可以像其他可观察对象一样订阅消息。行为主体的独特之处在于:

它需要一个初始值,因为它必须总是在订阅时返回一个值,即使它没有接收到next() 在订阅时,它返回主题的最后一个值。常规可观察对象只有在接收到onnext时才会触发 在任何时候,您都可以使用getValue()方法在不可观察的代码中检索主题的最后一个值。

与可观察对象相比,主体的独特特征是:

它是一个观察者,除了是一个可观察对象,所以你也可以发送值到一个主题,除了订阅它。

此外,你可以使用行为主体上的asObservable()方法从行为主体获取一个可观察对象。

Observable是一个泛型,而BehaviorSubject在技术上是Observable的子类型,因为BehaviorSubject是一个具有特定品质的可观察对象。

以行为主体为例:

// Behavior Subject

// a is an initial value. if there is a subscription 
// after this, it would get "a" value immediately
let bSubject = new BehaviorSubject("a"); 

bSubject.next("b");

bSubject.subscribe(value => {
  console.log("Subscription got", value); // Subscription got b, 
                                          // ^ This would not happen 
                                          // for a generic observable 
                                          // or generic subject by default
});

bSubject.next("c"); // Subscription got c
bSubject.next("d"); // Subscription got d

例2:常规主语:

// Regular Subject

let subject = new Subject(); 

subject.next("b");

subject.subscribe(value => {
  console.log("Subscription got", value); // Subscription won't get 
                                          // anything at this point
});

subject.next("c"); // Subscription got c
subject.next("d"); // Subscription got d

可以使用Subject . asobservable()从Subject和BehaviorSubject创建一个可观察对象。

唯一的区别是你不能使用next()方法将值发送到可观察对象。

在Angular服务中,我会为数据服务使用BehaviorSubject,因为Angular服务通常会在组件之前进行初始化,而behavior subject会确保使用该服务的组件接收到最后一次更新的数据,即使自该组件订阅该数据以来没有新的更新。