我正在研究Angular,目前我正在研究Observables。我现在明白什么是可观察量,包括主题,行为主题,重播主题。 但是我需要一个真实世界的例子,其中这些可以以不同的方式实际实现,以便我可以了解何时使用哪种方法。
例如,我可以看到/比较上述方法实现的任何应用程序。
当您希望从流中获得初始(默认)值时,可以使用BehaviorSubject
而不是Subject
。
假设您要检查用户是否登录:
与Subject
isLoggedIn$ = new Subject<boolean>();
.........
isLoggedIn$.subscribe(res => console.log(res))
在调用isLoggedIn$.next(someValue)
之前,此subscribe
不会触发。
但有了BehaviorSubject
isLoggedIn$ = new BehaviorSubject<boolean>(false); // <---- You give 'false' as an initial value
.........
isLoggedIn$.subscribe(res => console.log(res))
此subscribe
将立即触发,因为它将false
作为流中的值。
因此,如果您想要一个初始(默认)值,则需要使用BehaviorSubject
.
https://medium.com/@luukgruijs/understanding-rxjs-behaviorsubject-replaysubject-and-asyncsubject-8cc061f1cfc0
主体和行为主体有什么区别?
这是一个实际的例子,几乎没有解释。 假设您有一个包含许多components
的应用程序,例如:购物车,您有一个导航栏,显示添加到购物车中的商品。您有产品页面,带有许多添加到购物车按钮的项目网格。商品详情页面,其中有一个该产品的【添加到购物车】按钮。最后是订单摘要页面(即购物车页面,您可以在其中针对列表中的每个产品添加 + 或删除 - 的按钮。 在上述场景中,您可以在购物车服务上使用Subjects
或BehaviorSubject
。以及通过服务依赖关系注入订阅它的所有其他组件。添加到购物车按钮将调用服务的next()
功能。 如果您希望在用户离开会话时从浏览器本地存储(或其他机制)预填充购物车,只需将项目选择到购物车中但未完成交易过程即可。您可以使用BehaviorSubject
将初始负载到购物车。
为了扩展Yilmaz所写@Harun内容,必须从单页应用程序的不同部分检查用户登录状态,在这种情况下,您可以相应地使用,以检查用户的登录状态是否仍然有效。
不要与网络流和消息流混淆。 消息流与事件流结合使用。 请不要误会。 例如:网络流是你的地方,例如:套接字,你首先建立连接,然后交换数据包,如流。
在角度中,它的工作方式也类似,您可以通过订阅asObservable()
来建立连接。 像消息流一样交换数据。BehaviorSubject
向您发送欢迎消息,而使用者在调用next()
之前不发送任何消息
你去一家餐馆,服务员主动向你打招呼BehaviorSubject
服务员问候(我能帮你什么)当你打电话时Subject
楼层的所有服务员都在提供餐厅老板subscribed
的服务。
希望这有助于理解
更新于22/06/2020
上面提到的主题与响应式编程有关。 这意味着应用程序护罩对事件做出反应。 事件可以是默认的浏览器事件,如click
mouesevent
或任何可以发出的自定义事件。 例如,当用户添加到购物车时,下订单。之所以称为反应性,是因为事件是不确定的,我们不知道它何时会发生。例如。您订阅了YouTube频道,因为您不知道创作者何时会发布新视频,因此您设置了一种事件观察者。它将不断寻找该事件的发生。
因此,如果我创建一个不涉及服务器的示例单页 YouTube 应用程序。你将有一个creatorcomponent
,viewercomponent
,publishService
。 当创作者发布或发布视频时,它会调用publishService
并发送一条消息'new_video_published'
订阅该创作者的人将收到通知并viewerComponent
了解它。
现在,如果发布服务使用BehaviorSubject
来执行消息传递,则新订阅者(查看器)将立即获得该创建者发布的最新视频。如果 punlishService 使用Subject
则新订阅者将不会立即收到任何消息,而是收到所有消息。
publish.service.ts
... other code ...
subscribeMes$ = new Subject<string>();
//OR
//subscribeMeb$ = new BehaviorSubject<string>('Welcome Message');
newPublish(srting) {
this._name.next(string);
}
viewer.component.ts
//injecting service
subscribedOn_21022020(){
this.publishService.subscribeMes$.subscribe(n=>{
this.newVideo =n
})
}
subscribedOn_23022020(){
this.publishService.subscribeMes$.subscribe(n=>{
this.newVideo = n
})
}
creator.component.ts
this.publishService.newPublish('new video on Rxjs on 22/02/20')
在上面的示例中,我们看到当应用程序于 21-02-2020 在浏览器中首次加载时,因为没有发布视频(假设事件场景)。 当publish.service.ts
使用主题时,subscribedOn_21022020()
不会收到任何欢迎消息。如果使用BehaviorSubject
,他们将收到Welcome message
。在22/02/2020
,创作者发布一个视频,因此subscribedOn_21022020()
将收到新的视频消息,(如果BehaviorSubject
这将是他的第二条消息)。现在在23-02-2020上,第二个用户订阅subscribedOn_23022020()
今天他不会立即收到任何消息,但将来任何时候都会收到新的视频发布通知,因为发布服务使用主题。如果使用BehaviorSubject
,第二个订阅者将在订阅后立即收到'new video on Rxjs on 22/02/20'
消息。并继续获取未来的视频。
我使用行为主题在父组件和子组件之间以及同级组件之间发送消息。
这是行为主题的示例,它可能会对您有所帮助 https://stackblitz.com/edit/behavior-subject-2019
当您具有初始值时,可以使用行为主题。如果您正在使用authService并希望初始值为"null",我们使用BehaviorSubject。
我们不能使用主题,因为主题本质上是热门的。这意味着即使有人不听,它也会发出值。这意味着,如果我们在发出事件后太晚才开始订阅该主题,我们将不会收到该事件。
我们需要确保,在组件订阅的那一刻,它们被告知发出的最新值。这就是我们使用 BehaviorSubject 的原因,因为它会在组件订阅时发出最新值。