RefCount: automatically starting and stopping an execution

André Staltz
InstructorAndré Staltz

Share this video with your friends

Send Tweet
Published 6 years ago
Updated 4 years ago

With the connect() method on a ConnectableObservable, the programmer is responsible for avoiding leaked executions of shared RxJS Observables. This lesson will teach you about refCount(), a handy operator that creates an automatically connected Observable, to avoid manually using connect().

[00:00] With Connect and Unsubscribe, we were able to manually control when to start and stop the shared execution of the source observable. If we didn't do that, we could create a leak, so the responsibility is on the programmer to avoid these.

[00:14] It would be nicer if the observable would automatically connect and unsubscribe, so then we couldn't leak the shared execution at all. There's an operator for that called refCount. It stands for reference counting, and it exists on the connectable observable. Just like there is .connect, there is also .refCount. That's an operator to return an observable.

[00:41] This observable, we're actually going to name it auto connected observable. This is a normal observable. It's not a connected observable. As we saw, the connectable observable's rather different, because it has .connect, and it also has, as we see now, reference counting.

[01:00] RefCount is special, only for connectable observables. It basically means auto-connect. It returns us this auto-connected observable, which is a normal observable.

[01:10] How do we use this one? Normally, we can subscribe to it. Instead of subscribing to the connectable observable, we can subscribe to the auto-connected observable with Observer A. We can also do that with Observer B. Since the connect will happen automatically, we don't need this manual call to the connect anymore.

[01:32] When does the connect actually happen? It follows a simple rule, which is based on reference counting. It looks at the number of current subscribers. This is the number of current subscribers. If that number changes from zero to one, then it will connect, or subscribe, to the source. If that number changes back from one to zero, then it will unsubscribe. That's the reference counting rule.

[02:00] If we read this code from top to bottom, at this point when we define this observable, this doesn't have any subscriber, but here, we're essentially adding Observer A to the connectable observable. Before this line, the number of observables was zero. After this line, the number is one. That's when, exactly, it will perform the connect, or start the execution. It's because the number of observers changed from zero to one.

[02:33] After two seconds, that number will change from one to two, but there's no special rule in that case, so it just keeps on going. After five seconds, we can unsubscribe. The number went from two to one. Here, let's put that. It went from one to two.

[02:55] It won't actually unsubscribe. If we do, after, let's say, seven seconds, we unsubscribe B, then that number will go from one to zero. That's when the shared execution will stop. This means a stop.

[03:15] Let's give this a Run. We see initially that A subscribes, and that's what triggers the shared execution start. B subscribes at some other point in time, like here. After a while, A unsubscribes, but that's not enough to stop the shared execution. After B unsubscribes, the number of observers on that auto-connected one changed from one to zero.

[03:42] That's when it unsubscribed. As you can see, we have no leak here.

[03:47] This is nicer. RefCount is good, because we don't need to manually worry about when to connect and when to stop. We just know that this is an observable that has a shared execution, and that shared execution starts and stops automatically according to the current number of observers.

[04:07] Usually we can write this just after Multicast. Instead of making a separate observable, I'm going to call this one Shared. It will be Multicasted on the subject, and it will be refCounted. It's a normal observable for the other observers to subscribe to, and it works in the same way.

[04:32] This is how we do. After Multicast, we put refCount. It turns out that we don't use .connect to share this execution, but we trust on refCount to do that automatically for us.