Multicasting angular là gì?
Many times in Angular application development we’ll have an Observable, and want to use the values from that Observable to do different things in the UI. Let’s imagine we’re building this interface that shows information about a fish, and we want to show users a schedule of when that fish is available based on the hemisphere of the world selected. In our component we’ll get the response of an HTTP request to the animal crossing API. We’re using HTTPClient which returns an Observable. We want to display data from that HTTP request in our UI so a user can see information about the fish, but we also want to display a custom built schedule based on that data and input from something else. The API returns an object that looks something like this:
We want to get the availability based on the hemisphere(northern or southern) the user cares about, and display the months during which that fish is available, by creating an array like this:
We might consider doing something like this (note we are using the Async pipe in our component template to subscribe to
This will give us a But by doing this we’re creating an additional subscription to How can we avoid this? Instead of an Observable, we can use a Subject instead. Subjects can have multiple subscribers and only execute their context once. To convert an Observable to a Subject we can use the multicast operator. The multicast operator is a bit of a bear to understand - it takes a selector as a parameter and according to the docs returns
A more palatable summary from the docs is
So let’s pipe the multicast operator to source Observable 1 (because we want late subscribers to get the value).On the Subject of Subjects … subject - a special type of Observable that allows values to be multicasted to many Observers behaviorSubject - a subject that can ‘store’ a current value that new subscribers will receive replaySubject - a subject than can send old values to new subscribers
… now we have nothing displaying in our UI? Why? We still have the async pipe subscribing to 4 method on it to trigger our source observables execution.However, this means we must also remember to unsubscribe from that subscription created by the connect method, so doesn’t that defeat the purpose of using the async pipe? Yep. Boo. BUT, fear not, gentle reader, we can use the 5 operator, instead of having to manage the 4 method ourselves.
RefCount returns an Observable that keeps track of how many subscribers it has, it will start executing when subscribers is more than 0, and stops when subscribers are 0 again. This means when we use our async pipe on Our final code looks something like this
In summary, when we have an Observable we’d like to use a source for various purposes without executing its context every time, we can use the 9 operator to take a Subject and use it to share the source execution of our source Observable. The multicast operator returns a ConnectableObservable type, on which we CAN use the 4 method to create the subscription to our source Observable(the HTTP request to get a fish). A more management approach is to use the refCount operator which will count subscriptions and call the 4 method to subscribe to the source Observable once the first subscription is created and run tear down logic when the subscription count returns to 0 (AKA all the subscriptions have been unsubscribed). |