Reputation:
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
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