Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accomplishing shareValue/shareBehavior

Tags:

rxjs5

I have an Observable that is based on some events and at some point does some expensive computation. I would like to render the results from that Observable in multiple different places. If I naively subscribe to this Observable in two places I will end up doing the expensive computation twice. Here is a code snippet to drive my point home:

var s = new rx.Subject();
var o = s.map(x => { console.log('expensive computation'); return x });
o.subscribe(x => console.log('1: ' + x));
o.subscribe(x => console.log('2: ' + x));
s.next(42);

The output is:

expensive computation
1: 42
expensive computation
2: 42

I would like to perform the expensive computation in the map only once. share accomplishes this, but it makes it so late-arriving subscribers do not get the current value to render. In previous RxJS versions, shareValue allowed late-arriving subscribers to get the current value. However, it appears that this was renamed to shareBehavior in RxJS 5 and then removed altogether:

https://github.com/ReactiveX/rxjs/pull/588

https://github.com/ReactiveX/rxjs/pull/712

There is a long discussion in this issue where it was decided that they would 'Remove shareBehavior and shareReplay to prevent user confusion.' I don't understand what the potential for confusion was (so maybe that means I am one of the users saved by this decision?).

publishBehavior also looks promising but I don't fully understand publish and it seems like it adds more complexity than I need or want.

Anyway, I would like to know if there is a recommended way to accomplish this in RxJS 5. The migration doc doesn't provide any recommendations.

like image 884
Nat Mote Avatar asked May 03 '16 22:05

Nat Mote


1 Answers

After some more research I've found that the behavior I've described can be implemented with

.publishBehavior(startValue).refCount().

This discovery is based on the fact that share() is an alias for publish().refCount(). I still don't fully understand publish() but this seems to have the desired effect in practice.

Similar is cache(1) (which is an alias for publishReplay(1).refCount()). It has a similar effect as publishBehavior(defaultValue).refCount() except that it does not start with a default value. So if no items have been emitted, new subscribers will not immediately receive a value.

like image 97
Nat Mote Avatar answered Dec 22 '22 10:12

Nat Mote