我一直在寻找了解这三个:
我想使用它们,知道何时以及为什么使用它们,使用它们有什么好处,尽管我已经阅读了文档、观看了教程并搜索了谷歌,但我对此没有任何理解。
那么他们的目的是什么?一个真实的案例将是最值得赞赏的,它甚至不需要编码。
我更喜欢一个清晰的解释,而不仅仅是“a+b => c 你订阅了……”
谢谢
原文由 user6015054 发布,翻译遵循 CC BY-SA 4.0 许可协议
我一直在寻找了解这三个:
我想使用它们,知道何时以及为什么使用它们,使用它们有什么好处,尽管我已经阅读了文档、观看了教程并搜索了谷歌,但我对此没有任何理解。
那么他们的目的是什么?一个真实的案例将是最值得赞赏的,它甚至不需要编码。
我更喜欢一个清晰的解释,而不仅仅是“a+b => c 你订阅了……”
谢谢
原文由 user6015054 发布,翻译遵循 CC BY-SA 4.0 许可协议
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
请注意迟到的订阅是如何丢失一些被推送到主题中的数据的。
这是重播主题的使用示例,其中 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
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/
原文由 Varun Sukheja 发布,翻译遵循 CC BY-SA 4.0 许可协议
13 回答12.9k 阅读
7 回答2.1k 阅读
3 回答1.3k 阅读✓ 已解决
1 回答3.7k 阅读✓ 已解决
2 回答1.3k 阅读✓ 已解决
6 回答1.2k 阅读✓ 已解决
6 回答1.1k 阅读
它真的归结为行为和语义。与
Subject
- 订阅者只会获得订阅 后 发出的发布值。问问自己,这是你想要的吗?订户是否需要了解有关先前值的任何信息?如果没有,那么你可以使用这个,否则选择其他之一。例如,组件到组件的通信。假设您有一个组件,可以在单击按钮时为其他组件发布事件。您可以使用具有主题的服务进行通信。BehaviorSubject
- 最后一个值被缓存。订阅者将在初始订阅时获得最新值。该主题的语义是表示随时间变化的值。例如登录用户。初始用户可能是匿名用户。但是一旦用户登录,新值就是经过身份验证的用户状态。BehaviorSubject
用初始值初始化。这有时对编码偏好很重要。比如说你用null
初始化它。然后在您的订阅中,您需要进行空检查。也许还好,也许很烦人。ReplaySubject
- 它最多可以缓存指定数量的发射。任何订阅者都将在订阅时获得所有缓存的值。你什么时候需要这种行为?老实说,我不需要这样的行为,除了以下情况:如果您初始化
ReplaySubject
的缓冲区大小为1
,那么它实际上 表现 得就像BehaviorSubject
。最后一个值总是被缓存,所以它就像一个随时间变化的值。有了这个,就不需要null
检查就像 --- 用null
BehaviorSubject
初始化一样在这种情况下,在第一次发布之前,不会向订阅者发送任何值。所以它真的归结为您期望的行为(至于使用哪一个)。大多数时候您可能想要使用
BehaviorSubject
因为您真正想要表示的是“随时间推移的价值”语义。但我个人认为用ReplaySubject
初始化的1
的替换没有任何问题。当您真正需要的是一些缓存行为时,您要 避免 使用 vanilla
Subject
。举个例子,你正在写一个路由守卫或一个解决方案。您在该守卫中获取一些数据并将其设置在服务中Subject
。然后在路由组件中,您订阅服务主题以尝试获取在守卫中发出的值。哎呀。价值在哪里?它已经发出了,DUH。使用“缓存”主题!也可以看看: