I am experimenting with reactive programming for the first time using bacon.js and hit the odd interaction annoying me. I came up with a working version of this chain of events, but hacking manipulations with additional threads make it different from the rest of the code - as you will see.
I found FRP / Bacon.js to create fairly clean code, so it seems to me that I'm just missing some obvious operators. To the problem, will we?
Several sources recommend using Observable.flatMapLatestto remove obsolete events. Suppose we want to complete an I / O operation for each event in the input stream. The following diagram irepresents the events of the input stream, rNrepresents the events of each of the request flows, and xes indicate the point in time when the request flow was canceled. These are most likely streams with a single event, therefore, it .means that the stream is actually closed after the event (if it has not been canceled before!).
input stream: iββiββββββββiβββiβββββββββ>
request: β β β βββββr4.ββ>
request: β β ββββxβr3.βββββ>
request: β βββr2.βββxβββββββββββββ>
request: βββxβββββr1.ββββββββββββββ>
+
i.flatMapLatest(requests): ββββββr2βββββββββββββr4βββ>
This is perfectly normal for a few use cases, but pay attention to r3: it is never accepted, although it was still a valid answer until it reaches r4. In the worst case, many requests disappear:
input stream: iββiββiβββiββiββββββ>
request: β β β βββxβr4.ββ>
request: β β ββββxβr3.βββββ>
request: β βββxβr2.βββββββββ>
request: βββxβββββr1.ββββββββ>
+
i.flatMapLatest(requests): ββββββββββββββββββββ>
, throttle debounce , () . , ( 0,5 -5 +) .
, , , FRP. , , :
input stream: iββiββββββββiβββiβββββββββ>
request: β β β βββββr4.ββ>
request: β β ββββββr3.βxβββ>
request: β βββr2.ββββββββββxββββββ>
request: βββββββxβr1.ββββββββββββββ>
+
i.flatMap_What?(requests): ββββββr2ββββββββββr3βr4βββ>
flatMapLatest one:
var wrong = function (interval, max_duration) {
var last_id = 0,
interval = interval || 1000,
max_duration = max_duration || 5000;
Bacon.interval(interval, 'bang').log('interval:')
.flatMapLatest(function () {
return Bacon.later(Math.random()*max_duration, last_id++).log(' request:');
})
.log('accepted: %s **********');
};
var right = function (interval, max_duration) {
var last_id = 0,
interval = interval || 1000,
max_duration = max_duration || 5000;
Bacon.interval(interval, 'bang').log('interval:')
.flatMap(function () {
return Bacon.later(Math.random()*max_duration, last_id++).log(' request:');
})
.diff(-1, function (a, b) { return b > a ? b : -1 })
.filter(function (id) { return id !== -1 })
.log('accepted: %s **********');
};
wrong , , right flatMap diff filter. , timestamp/id , .
, , : ? ? takeUntil flatMap () ()?
, !