主体与行为主体与重播角度中的主体

我一直在寻找理解这3个:

我想使用它们,并知道何时以及为什么,使用它们有什么好处,尽管我已经阅读了文档,观看了教程并搜索了Google,但我没有对此有任何理解。

那么它们的目的是什么呢?一个现实世界的情况将是最值得赞赏的,它甚至不必编码。

我更喜欢一个干净的解释,而不仅仅是“a + b = > c你订阅了......”。

谢谢


答案 1

它实际上归结为行为和语义。使用

  • Subject- 订阅者将仅获取订阅发出的已发布值。问问自己,这是你想要的吗?订阅者是否需要了解有关以前值的任何信息?如果没有,那么您可以使用它,否则请选择其他一个。例如,使用组件到组件的通信。假设您有一个组件,该组件在单击按钮时发布其他组件的事件。您可以使用带有主题的服务进行通信。

  • BehaviorSubject- 最后一个值被缓存。订阅者将在初始订阅时获得最新值。此主题的语义表示随时间变化的值。例如,已登录的用户。初始用户可能是匿名用户。但是,一旦用户登录,新值就是经过身份验证的用户状态。

    使用初始值初始化 。这有时对于编码首选项很重要。例如,假设您使用 .然后在订阅中,需要执行空检查。也许还行,也许很烦人。BehaviorSubjectnull

  • ReplaySubject- 它可以缓存多达指定数量的排放。任何订阅者都将在订阅时获取所有缓存的值。何时需要此行为?老实说,除了以下情况外,我没有任何需要这样的行为:

    如果初始化 的缓冲区大小为 ,则它实际上的行为就像 .最后一个值始终是缓存的,因此它的作用类似于随时间变化的值。这样,就不需要像用 .在这种情况下,在第一次发布之前,不会向订阅服务器发出任何值。ReplaySubject1BehaviorSubjectnullBehaviorSubjectnull

因此,它实际上归结为您期望的行为(例如使用哪一个)。大多数时候,您可能希望使用 a,因为您真正想要表示的是“随时间推移的价值”语义。但我个人认为用.BehaviorSubjectReplaySubject1

您要避免的是使用香草,而您真正需要的是一些缓存行为。例如,您正在编写路由保护或解析。您可以在该防护中获取一些数据并将其设置在服务中。然后在路由组件中,订阅服务主体以尝试获取在防护中发出的值。哎呀。价值何在?它已经发出来了,DUH。使用“缓存”主题!SubjectSubject

另请参阅:


答案 2
  1. 主题:订阅时,它总是获取订阅后推送的数据,即不接收以前的推送值

const mySubject = new Rx.Subject();

mySubject.next(1);

const subscription1 = mySubject.subscribe(x => {
  console.log('From subscription 1:', x);
});

mySubject.next(2);

const subscription2 = mySubject.subscribe(x => {
  console.log('From subscription 2:', x);
});

mySubject.next(3);

subscription1.unsubscribe();

mySubject.next(4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.12/Rx.min.js"></script>

在此示例中,下面是将在控制台中打印的结果:

From subscription 1: 2  
From subscription 1: 3  
From subscription 2: 3  
From subscription 2: 4  

请注意,延迟到达的订阅如何丢失已推送到主题中的某些数据。

  1. 重播主题:可以通过保留将发出到新订阅的先前值的缓冲区来提供帮助。

下面是重播主题的用法示例,其中 a 在新订阅上保留和发出:buffer of 2 previous values

const mySubject = new Rx.ReplaySubject(2);

mySubject.next(1);
mySubject.next(2);
mySubject.next(3);
mySubject.next(4);

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.12/Rx.min.js"></script>

以下是我们在控制台上提供的内容:

From 1st sub: 3
From 1st sub: 4
From 1st sub: 5
From 2nd sub: 4
From 2nd sub: 5
  1. 行为主体:类似于重播主体,但只会重新发出最后一个发出的值,如果以前未发出任何值,则为默认值:

const mySubject = new Rx.BehaviorSubject('Hey now!');

mySubject.subscribe(x => {
  console.log('From 1st sub:', x);
});

mySubject.next(5);

mySubject.subscribe(x => {
  console.log('From 2nd sub:', x);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.12/Rx.min.js"></script>

结果:

From 1st sub: Hey now!
From 1st sub: 5
From 2nd sub: 5

参考资料: https://alligator.io/rxjs/subjects/