我对Subject类的功能和使用方法有相当不错的了解,但是我刚刚在msdn的语言参考中查看时发现还有其他各种ISubject实现,例如:
- AsyncSubject
- BehaviorSubject
- ReplaySubject
由于文档非常匮乏,每种类型的用途是什么以及在什么情况下使用它们呢?
我对Subject类的功能和使用方法有相当不错的了解,但是我刚刚在msdn的语言参考中查看时发现还有其他各种ISubject实现,例如:
由于文档非常匮乏,每种类型的用途是什么以及在什么情况下使用它们呢?
这些主题都具有一个共同的特点-它们通过OnNext接收并记录发布给它们的一些(或全部)内容,并将其回放给您-即,它们获取热可观察对象并使其变为冷的。这意味着,如果您订阅其中任何一个超过一次(即订阅= >取消订阅= >再次订阅),则您将再次看到至少一个相同的值。
ReplaySubject:每次订阅Subject时,会尽可能快地回放已发布的整个历史记录(或子集,例如最后n 项)
AsyncSubject:始终回放最后一项已发布的内容并完成,但仅在源已完成后才这样做。对于异步函数,此主题非常有用,因为您可以编写它们而不必担心竞争条件:即使在异步方法完成后有人订阅,他们也会获得结果。
BehaviorSubject:类似于ReplaySubject,但具有缓冲区,缓冲区大小为1,因此您始终获取最后发布的内容。您还可以提供初始值。始终在订阅时立即提供一个项目。
考虑到最新版本(v1.0.2856.0)并为了保持这个问题的最新状态,已经推出了一组新的主题类:
FastSubject
、FastBehaviorSubject
、FastAsyncSubject
和FastReplaySubject
根据发布说明,它们比普通主题快得多,但是:
没有通过IScheduler分离生产者和消费者(有效地将它们限制在ImmediateScheduler中);
不保护堆栈溢出; 不同步输入消息。 如果未指定调度程序,则Publish和Prune操作符使用快速主题。
这段代码:
var s = new AsyncSubject<int>();
s.OnNext(1);
s.Subscribe(Console.WriteLine);
s.OnNext(2);
s.OnNext(3);
s.OnCompleted();
打印单个值3。如果将订阅移到完成后,则会打印相同的内容。因此,它回放的不是第一个项目,而是最后一个项目,在完成后播放(在完成之前,它不会产生值),并且在完成之前不像Subject那样工作。 有关更多信息,请参见此Prune讨论(AsyncSubject基本上与Prune相同)。
Paul的答案基本上解决了问题。但还有一些值得补充的地方:
AsyncSubject像Paul所说的那样工作,但只有在源完成后才能生效。在此之前,它的工作方式类似于Subject
(订阅者接收到“实时”值)。
AsyncSubject自我上次测试以来已经发生了变化。在完成之前,它不再像活动主题那样工作,而是等待完成后才发出值。正如Sergey提到的那样,它返回最后一个值,而不是第一个值(尽管我应该注意到这一点,因为这始终是这种情况)
AsyncSubject被Prune
、FromAsyncPattern
、ToAsync
和可能还有其他一些函数使用
BehaviorSubject被Publish
的重载函数使用,这些函数接受一个初始值
ReplaySubject被Replay
使用
注意:上面所有运算符引用都指发布集合运算符,在rev 2838(2010年圣诞节)被通用发布运算符替换之前,它们被提到过原始运算符将被重新添加
IConnectableObservable
提供了一种将它们全部断开连接的方法。 - Ana Betts