question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unsubscription doesn't work after shareReplay?!

See original GitHub issue

RxJS version: 5.5.2

Code to reproduce:

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

<button id="foo">Foo</button>
<button id="bar">Bar</button>

<script>
  let {Observable: O} = Rx

  let fooNode = document.querySelector("#foo")
  let barNode = document.querySelector("#bar")

  let fooClick$ = O.fromEvent(fooNode, "click")
    .do(() => { console.log("foo clicked!") })

  let barClick$ = O.fromEvent(barNode, "click")
    .do(() => { console.log("bar clicked!") }).shareReplay(1) // !!! 

  let fooSb = fooClick$.subscribe()
  let barSb = barClick$.subscribe() // !!!

  setTimeout(() => {
    fooSb.unsubscribe()
  }, 2000)

  setTimeout(() => {
    barSb.unsubscribe() // !!!
  }, 2000)
</script>

Expected behavior:

Both buttons stop working after two seconds.

Actual behavior:

Only the first button stop working after two seconds.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:12

github_iconTop GitHub Comments

2reactions
cartantcommented, Nov 2, 2017

Given that the observable created with fromEvent is not going to complete, you can get the behaviour you want using multicast directly by replacing shareReplay(1) with multicast(() => new ReplaySubject(1)).refCount().

The implementation that preceded the referenced PR, was essentially the same, but included some special handling for sources that completed - which is not relevant here.

As far as I am aware, there is no documentation for shareReplay in RxJS version 5.

1reaction
shlomiassafcommented, May 3, 2018

Just use a custom operator, it’s dead simple

export const weakShareReplay = <T>(bufferSize?: number, windowTime?: number ) =>
  (source: Observable<T>) =>
    source.pipe(publishReplay(bufferSize, windowTime), refCount());

@benlesh this could be added to the library, maybe?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Share operator that doesn't unsubscribe - rxjs
1. The current implementation of shareReplay effects the behaviour you are after. It unsubscribes only when/if the source completes. See github.
Read more >
Be careful when using shareReplay
This post describes an issue with the current shareReplay operator in RxJS. There has been an open issue for this on Github, ...
Read more >
shareReplay
By default shareReplay will use refCount of false, meaning that it will not unsubscribe the source when the reference counter drops to zero,...
Read more >
Always Know When to Use Share vs. ShareReplay
The way share and shareReplay work is not always obvious and might ... Once the subscriber count reaches 0 , share will unsubscribe...
Read more >
ShareReplay - Angular - GitBook
// simulate url change with subject. const · = ; import { Subject } from 'rxjs/Subject';. import { ReplaySubject } from 'rxjs/ReplaySubject';. import...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found