我正在研究Angular RxJs模式,我不明白行为主体和可观察对象之间的区别。
根据我的理解,BehaviorSubject是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与可观察对象的目的完全相同。
什么时候使用可观察对象和行为主体?使用一个行为主体比使用一个可观察对象有好处吗?反之亦然?
我正在研究Angular RxJs模式,我不明白行为主体和可观察对象之间的区别。
根据我的理解,BehaviorSubject是一个可以随时间变化的值(可以订阅,订阅者可以接收更新的结果)。这似乎与可观察对象的目的完全相同。
什么时候使用可观察对象和行为主体?使用一个行为主体比使用一个可观察对象有好处吗?反之亦然?
当前回答
可观察对象和主体都是可观察对象,这意味着观察者可以跟踪它们。它们都有一些独特的特点。有三种类型的科目,每一种也有独特的特点。
您可以在stackblitz上找到实际示例。 (您需要检查控制台以查看实际输出)
观察
它们是冷的:当它们至少有一个观察者时,代码就会被执行。
创建数据副本:Observable为每个观察者创建数据副本。
单向:观察者不能给观察对象赋值(源/主)。
主题
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。
如果你正在使用subject,那么你会错过所有在创建观察者之前传播的值。这就是重放主题
ReplaySubject
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。+
重播消息流:无论您何时订阅重播主题,您都将收到所有的广播消息。
在Subject和ReplaySubject中,不能将初始值设置为observable。这就是行为主体…
BehaviorSubject
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。+
重播消息流:无论您何时订阅重播主题,您都将收到所有的广播消息。
你可以设置初始值:你可以用默认值初始化可观察对象。
其他回答
可观察对象和主体都是可观察对象,这意味着观察者可以跟踪它们。它们都有一些独特的特点。有三种类型的科目,每一种也有独特的特点。
您可以在stackblitz上找到实际示例。 (您需要检查控制台以查看实际输出)
观察
它们是冷的:当它们至少有一个观察者时,代码就会被执行。
创建数据副本:Observable为每个观察者创建数据副本。
单向:观察者不能给观察对象赋值(源/主)。
主题
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。
如果你正在使用subject,那么你会错过所有在创建观察者之前传播的值。这就是重放主题
ReplaySubject
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。+
重播消息流:无论您何时订阅重播主题,您都将收到所有的广播消息。
在Subject和ReplaySubject中,不能将初始值设置为observable。这就是行为主体…
BehaviorSubject
它们很热:即使没有观察者,代码也会被执行,值也会被传播。
共享数据:在所有观察者之间共享相同的数据。
双向:观察者可以给观察对象赋值(源/主)。+
重播消息流:无论您何时订阅重播主题,您都将收到所有的广播消息。
你可以设置初始值:你可以用默认值初始化可观察对象。
在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.
行为主体与主体相同,但也有初始的“种子”值。新订阅用户立即获得最新的值。如果有人订阅了行为主体,它会立即接收到最近的值。所以行为主体总有一些价值可以分给订阅者。
关于行为主体最有用的事情是当我们开始发出网络请求时。想象一下,我们将一些管道连接到一个行为主题上,在一个管道函数或管道操作符中,我们最终发出一个网络请求并获取一些数据。你最终可能会想让其他东西订阅那个可观察对象,并立即获得已经获取的数据。使用行为主体,我们可以很容易地实现这种行为。
app.component.ts
behaviourService.setName("behaviour");
behaviour.service.ts
private name = new BehaviorSubject("");
getName = this.name.asObservable();
constructor() {}
setName(data) {
this.name.next(data);
}
custom.component.ts
behaviourService.subscribe(response=>{
console.log(response); //output: behaviour
});
把Observables想象成一个管道,里面有流动的水,有时水流动,有时不流动。在某些情况下,你可能真的需要一个一直有水的管道,你可以通过创建一个特殊的管道来做到这一点,不管它有多小,让我们把这个特殊的管道称为行为主题,如果你恰好是你所在社区的供水供应商,你可以安心地睡在晚上,因为你新安装的管道只是工作。
在技术术语中:你可能会遇到一个可观察对象总是有价值的情况,也许你想要捕获输入文本的值,然后你可以创建一个BehaviorSubject的实例来确保这种行为,让我们说:
const firstNameChanges = new BehaviorSubject("<empty>");
// pass value changes.
firstNameChanges.next("Jon");
firstNameChanges.next("Arya");
然后,您可以使用“value”对随时间变化的更改进行抽样。
firstNameChanges.value;
这在你以后组合可观察对象时很方便,通过查看你的流的类型为BehaviorSubject,你可以确保流至少会触发或发出至少一次信号。
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会确保使用该服务的组件接收到最后一次更新的数据,即使自该组件订阅该数据以来没有新的更新。