简体   繁体   中英

In RxJS, why does a pipe get executed once for each subscription?

I want to have multiple subscriptions to react to an observable event, but I want to log the event as well, so I pipe it through a do() operator in which I do the logging.

The problem is, the event gets logged once for each of the subscriptions I create!

I'm getting around this at the moment by creating a Subject and calling next on it from an event callback, which allows me to log the event once and trigger multiple subscriptions as well.

Here is some code that demonstrates the issue: https://stackblitz.com/edit/rxjs-xerurd

I have a feeling I'm missing something, isn't there a more "RxJS" way of doing this?

EDIT:

I'm not asking for a difference between hot & cold observable, in fact I was using a hot observable - the one created by fromEvent() and was wondering why does my presumably hot event source behave like it's cold.

I realize now - after reading about share() - that pipe() "turns" your observable cold ie returns a cold one based on the your source (which may be cold, may be hot)

Because Observable sequences are cold by default, each subscription will have a separate set of site effects.

If you want your side effect to be executed only once - you can share subscription by broadcasting a single subscription to multiple subscribers. To do this you can use share , shareReplay , etc.

To better understand how it works, what is "cold" and publish, refer to the RxJS v4 documentation:

4.8 Use the publish operator to share side-effects

EDIT : share() is finally working. Please have a look to the comments below. Thx to @Oles Savluk.

I let my answer below for the records. It may help.


share() and multicasting stuffs did not solve my very similar issue.

Here is how I solved it : https://stackblitz.com/edit/rxjs-dhzisp

const finalSource = new Subject();
fromEvent(button3, "click").pipe(
  tap(() => {
    console.log("this happens only once")
  }) 
).subscribe(() => finalSource.next())

finalSource.subscribe(
  () => console.log("first final subscription")
)

finalSource.subscribe(
  () => console.log("second final subscription")
)

finalSource.subscribe(
  () => console.log("third final subscription")
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM