javascript - How to store accumulated result of a scan with rxjs -
i have 2 merged observables scan after merge. first 1 simple range , other subject. whenever subject emits new value onnext
concatenate value in scan , return new array accumulator. if dispose of subscription, , subscribe again replays values range have lost ones subject. in code below want second subscription have final value of [1, 2, 3, 4, 5]
what best way this? right have subject store final value , subscribe that, feels wrong.
here's simple version demonstrates happening:
var rx = require('rx'); var source = rx.observable.range(1, 3); var adder = new rx.subject(); var merged = source.merge(adder) .scan([], function(accum, x) { return accum.concat(x); }); var subscription1 = merged.subscribe(function(x) {console.log(x)}); adder.onnext(4); adder.onnext(5); subscription1.dispose(); console.log('after disposal'); var subscription2 = merged.subscribe(function(x) {console.log(x)});
this outputs:
[ 1 ] [ 1, 2 ] [ 1, 2, 3 ] [ 1, 2, 3, 4 ] [ 1, 2, 3, 4, 5 ] after disposal [ 1 ] [ 1, 2 ] [ 1, 2, 3 ]
a subject hot observable, that's why second subscription won't see events coming subject. range observable cold, each "execution instance" entirely owned each subscription. on other hand, subject's "execution instance" singleton , independent, hence second subscription doesn't see events.
there couple of ways of solving this.
- use replaysubject. have specify buffer size. if don't have limit buffer, using unlimited buffer might cause memory problems.
- avoid using subject. in other words, avoid using hot observable, replace cold observable, , according problem description gave in beginning, subscriptions wouldn't have problem , see same events. subject can replaced observable, depends on overall architecture. might need rewrite lot. , in worst case, such circular dependency of observables, cannot avoid using subject.
- rearrange code such subscriptions start before subject starts emitting, subscriptions chance see "live" emissions hot observables.
however, if interpretation of problem correct, need last event emitted merged
, use variant of alternative (1) replay last event. matter of adding .sharereplay(1)
merged
, make hot replayed observable.
Comments
Post a Comment