javascript - how to avoid glitches in Rx -


unlike other "frp" libraries, rx doesn't prevent glitches: callbacks invoked time-mismatched data. there way work around this?

as example, imagine have series of expensive computations derived single stream (e.g. instead of _.identity, below, sort, or ajax fetch). distinctuntilchanged avoid recomputing expensive things.

sub = new rx.subject(); = sub.distinctuntilchanged().share(); b = a.select(_.identity).distinctuntilchanged().share(); c = b.select(_.identity).distinctuntilchanged(); d = rx.observable.combinelatest(a, b, c, function () { return _.toarray(arguments); }); d.subscribe(console.log.bind(console)); sub.onnext('a'); sub.onnext('b'); 

the second event end causing number of glitchy states: 3 events out, instead of one, wastes bunch of cpu , requires explicitly work around mismatched data.

this particular example can worked around dropping distinctuntilchanged, , writing wonky scan() functions pass through previous result if input hasn't changed. can zip results, instead of using combinelatest. it's clumsy, doable.

however if there asynchrony anywhere, e.g. ajax call, zip doesn't work: ajax call complete either synchronously (if cached) or asynchronously, can't use zip.

edit

trying clarify desired behavior simpler example:

you have 2 streams, , b. b depends on a. b asynchronous, browser may cache it, can either update independently of a, or @ same time a. so, particular event in browser can cause 1 of 3 things: updates; b updates; both , b update. desired behavior have callback (e.g. render method) invoked once in 3 cases.

zip not work, because when or b fires alone, no callback zip. combinelatest not work because when , b fire 2 callbacks.

the concept

both , b update

where both a , b observables, doesn't exist primitive in rx.

there no lossless, general operator can defined decide when receives notification a whether should pass downstream or hold off until receives notification b. notifications in rx not natively carry "both" semantics, or semantics beyond rx grammar matter.

furthermore, rx's serial contract prevents operator taking advantage of overlapping notifications in attempt achieve goal. (though suspect relying on race conditions isn't desired approach anyway.)

see §§4.2, 6.7 in rx design guidelines.

thus, meant above "there no lossless, general operator can defined..." given 2 observables a , b independent notifications, operator attempts decide when receives notification a or b whether must push or wait "other" value, must rely on arbitrary timings. it's guesswork. hypothetical operator must either drop values (e.g., distinctuntilchanged or throttle), or drop time (e.g., zip or buffer), though combination of both.

therefore, if agent has ability push a alone, or b alone, or a , b notification unit, it's developer's responsibility reify concept of notification unit themselves.

a 3-state type required: | b | {a,b}

(please excuse lousy js)

var ab = function(a, b) { this.a = a; this.b = b; } sub.onnext(new ab('a'));        // process alone sub.onnext(new ab('a', 'b'));   // process , b sub.onnext(new ab(null, 'c'));  // process c alone 

the shape of observable's query no longer matters. observers must defined accept data type. it's generator's responsibility apply necessary buffering or timing calculations based on semantics of internal state in order produce correct notifications observers.

by way, thank providing simple explanation in edit (it seems clear me anyway). had first heard "glitches" in this rx forum discussion. can see, never concluded. wonder whether op's problem simple this, assuming i've understood problem correctly, of course. :-)

update:

here's related discussion, including more of thoughts on why rx not frp:

https://social.msdn.microsoft.com/forums/en-us/bc2c4b71-c97b-428e-ad71-324055a3cd03/another-discussion-on-glitches-and-rx?forum=rx


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -