Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

behaviour of publish + refCount !== share? #1363

Closed
christianacca opened this issue Feb 19, 2016 · 5 comments
Closed

behaviour of publish + refCount !== share? #1363

christianacca opened this issue Feb 19, 2016 · 5 comments

Comments

@christianacca
Copy link

Problem

My understanding is that share meant to be a shorthand equivalent to publish().refCount() - is my understanding correct?

If so then, I have noticed that there are cases where this is not so.

Example

Note: for the running example open codepen

Take for example:

let fakeUrlPrefixFetch$ = Rx.Observable.interval(2000).take(1);
let fakeMovieListFetch$ = Rx.Observable.interval(3000).take(1).map(x => [x]);
let fakeQueuedMoviesFetch$ = Rx.Observable.interval(2500).take(1).map(x => [x])

// let urlPrefixFetched$ = urlPrefixFetch$.share();
let urlPrefixFetched$ = fakeUrlPrefixFetch$.publish().refCount();

let movieListFetched$ = urlPrefixFetched$.flatMap(url => fakeMovieListFetch$);
let queuedMoviesFetched$ = urlPrefixFetched$.flatMap(url => fakeQueuedMoviesFetch$);
let allMoviesFetched$ = Rx.Observable.concat(movieListFetched$, queuedMoviesFetched$);

printTime("subz1 created");
let subz1 = allMoviesFetched$.subscribe(
  x => printTime(`subz1 ${JSON.stringify(x)}`), 
  null, 
  _ => printTime("subz1 completed"));

The subscribed observer receives items emitted from movieListFetched$ but NOT from queuedMoviesFetched$.

Whereas the if you replace the publish().refCount() with:

let urlPrefixFetched$ = fakeUrlPrefixFetch$.share();

... the subscriber end up receiving items from BOTH movieListFetched$ and queuedMoviesFetched$.

My guess at an explanation

My guess is that with publish().refCount(), the observable produced (urlPrefixFetched$) is not being disconnected when the concat operator switches from emitting items from the second observable.

As a consequence fakeUrlPrefixFetch$ is already completed.

On the other hand with share, at the point of concat moving between observables, urlPrefixFetched$'s ref count drops to 0. It is then reconnected to causing the cold observable (urlPrefixFetch$) to emit a new set of (1) items.

@plievone
Copy link
Contributor

My understanding is that share meant to be a shorthand equivalent to publish().refCount() - is my understanding correct?

I don't know the specifics, but from the source it looks like .share() is a shorthand for .multicast(() => new Subject()).refCount() whereas .publish() is a shorthand for .multicast(new Subject()). That factory function makes a difference according to the test cases:
https://github.com/ReactiveX/RxJS/blob/master/spec/operators/multicast-spec.js
https://github.com/ReactiveX/RxJS/blob/master/spec/operators/publish-spec.js
https://github.com/ReactiveX/RxJS/blob/master/spec/operators/refCount-spec.js
https://github.com/ReactiveX/RxJS/blob/master/spec/operators/share-spec.js

@trxcllnt
Copy link
Member

@christianacca @plievone yes, we finally decided to fix a long-standing backwards-incompatible bug with multicast in v5. We've kept the old behavior in the publish operators (reusing the Subject), but opted for the fixed behavior in the share operators (recreating the Subject). More context is available here #453 (comment) #453 (comment)

@christianacca
Copy link
Author

OK, I see that was a hard decision to make.

Of course expect this to trip quite a number of devs up simply because there are a lot of existing historical mentions (eg) that share is equivalent.

@OliverJAsh
Copy link
Contributor

Related issue: #1914

It would be good to fix the docs here to avoid further confusion.

@lock
Copy link

lock bot commented Jun 6, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants