I already wrote about Publish, Connect and RefCount in RxSwift . In order to better cover the topic, I present to your attention the translation of another wonderful article about the differences between operators such as share (), replay (), replayAll (), shareReplay (), publish () and shareReplayLatestWhileConnected ().A common mistake that newcomers make when taking up
Rx is misunderstanding that the chain of operators on the Observable is re-executed with each new subscriber:
let results = query.rx.text .flatMapLatest { query in networkRequestAPI(query) } results.subscribe(...)
We have several subscribers to a single Observable, but we do not want its code to be executed with each new Subscriber. For this, there are several operators in
RxSwift . Here is a summary sign describing each one of them:
')
1 - retransmits elements produced before subscription no more than bufferSize.
2 - retransmits 1 element generated before the subscription, as long as at least one subscriber exists.Now consider in detail each property.
Shared subscription. The returned Observable shares one major subscription among all subscribers.
let results = query.rx.text .flatMapLatest { query in networkRequestAPI(query) } .___()
Connectable. The return Observable will not produce elements until the
connect()
method is called.
Reference counting. The returned Observable counts the number of subscriber subscribed to. As we remember from the first property, on Observable, to which the operator was applied (we will call it Source Observable), there is always only one “primary” subscription and it shares data with the rest of the subscribers.
let sourceObservable = query.rx.text .flatMapLatest { query in networkRequestAPI(query) } let resultObservable = sourceObservable.share() resultObservable.subscribe(...) resultObservable.subscribe(...) resultObservable.subscribe(...)
When the subscriber count reaches zero, Source Observable resources are cleared. Note:
each time the counter is increased from zero to one, a new subscription will be made to the Source Observable. But this may not happen if the Source Observable has completed or sent an error. This is a rather unpredictable behavior, so I try to avoid it and when writing code I am convinced that after the number of subscribers has dropped to zero, there will be no subsequent subscriptions.
Replays events. The operator relays items from Source Observable to subscribers who have already subscribed after Source Observable began producing items. For
replay(bufferSize)
and
shareReplay(bufferSize)
number of these elements is no more than bufferSize. For
shareReplayLatestWhileConnected()
this number is not greater than one. Unlike
shareReplay(bufferSize)
,
shareReplayLatestWhileConnected()
clears the buffer when the number of subscribers drops to zero. Therefore, when Subscriber subscribes, which increases the counter from zero to one, it will not receive any items.
It is also worth mentioning the
multicast
operator, which can be useful if you use
Subject
. But, the operators described in this article are likely to be enough for most user cases.
Translator's note.
For completeness, I advise you to read:
- An article about Publish, Connect and RefCount in RxSwift , it said about the first three properties described above.
- RxSwift cheat sheet for operators . The author has done a lot of work and collected in one place all the basic RxSwift operators, their descriptions with pictures and code examples. I myself periodically glance at the cheat sheet if I need to remember any operator.
- Official RxSwift documentation , of course.
If something remains unclear, please let me know in the comments.