I have this:
var bulk = array[1,2,3,4]
var finalResult = Bacon
.fromArray(bulk)
.flatMap(isValInCouchDb)
.filter(onesThatExist)
.flatMap(putValInCouchDb)
I need right after the filter to delay the whole stream by 1 second and then run putValInCouchDb Something like this really:
var bulk = array[1,2,3,4]
var finalResult = Bacon
.fromArray(bulk)
.flatMap(isValInCouchDb)
.filter(onesThatExist)
.delay(1000)
.flatMap(putValInCouchDb)
But I think I'm missing something because .delay(1000) is delaying everything for as many seconds as there are items and then runs them all once all the time has lapsed.
Any ideas ?
UPDATE
Just to clarify based on the answer from Alex
What I would need is:
1 "filter" 1
2 "filter" 2
3 "filter" 3
4 "filter" 4
[waits 1 second]
1004 "flatMap" 1
[waits 1 second]
2004 "flatMap" 2
[waits 1 second]
3005 "flatMap" 3
[waits 1 second]
4006 "flatMap" 4
UPDATE 2 - With Solution Used
From the answer from Bergi, using .zip with an interval actually worked but what happens with .zip is that .interval creates an event every second and then each event from .interval waits for each event from my database checks. A lot of database checks happen in bulk and very fast so 'excessive buffering' occurs (which is what the bacon docs warn you).
So I decided to do it this way instead:
var bulk = array[1,2,3,4]
var finalResult = Bacon
.fromArray(bulk)
.flatMap(isValInCouchDb)
.filter(onesThatExist)
.fold([], function(a, b){ a.push(b); return a })
.flatMap(function(a){return Bacon.sequentially(1500, a)})
.flatMap(putValInCouchDb)
This worked nicely since folding the filtered results and sequentially creating events from them is natural, very descriptive, and without side effects.
Bacon is quite awesome
Unless you are doing something fancy in putValInCouchDb
, your code appears to work exactly as you wish it would. Eg, running
var t = new Date().getTime();
function timestamp(label, x) { console.log(new Date().getTime() - t, label, x); }
var s = Bacon.fromArray([1,2,3,4])
.filter(function(x) { timestamp("filter", x); return true })
.delay(1000)
.flatMap(function(x) { timestamp("flatMap", x); return Bacon.constant(x) })
s.onValue(function(x) {})
outputs something like
1 "filter" 1
2 "filter" 2
3 "filter" 3
4 "filter" 4
[waits 1 second]
1004 "flatMap" 1
1004 "flatMap" 2
1005 "flatMap" 3
1006 "flatMap" 4
.delay(1000) is delaying everything for as many seconds as there are items and then runs them all once all the time has lapsed.
Yes, that's just what delay
is supposed to do: take each event and fire it after a given delay.
There is no extra function that does delay and buffer at the same time, both throttle
and debounce
will swallow events that occured too fast.
What you can do is:
Bacon.sequentially
to which you can pass the 1s-interval instead of the plain Bacon.fromArray
to construct your stream Use zip
to join your existing event stream into events that occur at the expected time:
Bacon.fromArray(bulk)….zip(Bacon.interval(1000), _.id)
I'm not sure though how your .flatMap(isValInCouchDb)
manipulates the stream.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.