user358089
user358089

Reputation:

RxJS Observable.fromEvent chain firing for each subscriber

I've made a key service for a keyboard-driven interface, and I've found that it seems to execute the full chain for each subscriber:

this.documentKeyEvent = Observable.fromEvent(document, 'keydown')
  .do((e: KeyboardEvent) => console.log(e.keyCode || e.which))
  .filter((e: KeyboardEvent) => !isKeyModified(e) && !!Keys[remap(e.keyCode || e.which)])
  .do((e: KeyboardEvent) => e.preventDefault())
  .throttle(() => Observable.timer(100))
  .map((e: KeyboardEvent) => remap(e.keyCode || e.which));

The console.log in the first .do() executes three times because there are three subscribers. This isn't necessarily a problem, but seems like that would get pretty inefficient as more components subscribe to it.

Is there a way to only execute that chain once per event, and then push those results to all the subscribers to then do whatever they want with?

Thanks

Upvotes: 0

Views: 859

Answers (1)

Olaf Horstmann
Olaf Horstmann

Reputation: 16882

Yes, you can either use share as your last operator:

this.documentKeyEvent = Observable.fromEvent(document, 'keydown')
  .do((e: KeyboardEvent) => console.log(e.keyCode || e.which))
  .filter((e: KeyboardEvent) => !isKeyModified(e) && !!Keys[remap(e.keyCode || e.which)])
  .do((e: KeyboardEvent) => e.preventDefault())
  .throttle(() => Observable.timer(100))
  .map((e: KeyboardEvent) => remap(e.keyCode || e.which))
  .share();

This will essentially share the stream between all subscribers.

Note: share is an alias for publish().refCount() - see the docs for details on: publish

Upvotes: 1

Related Questions