0

Is there a way to combine two streams S1 and S2 into a third S3 which emits on the first S2 event AFTER S1 has emitted?

For example:

S1 --*----------------*------*--*--*-----------
S2 ------*--*--*----------*-----------*--*--*--
S3 ------*----------------*-----------*--------

Right now I'm doing it like this, but it's probably not very efficient and doesn't capture the semantics:

S1.sampledBy(S2).skipDuplicates()
estolua
  • 677
  • 4
  • 11

1 Answers1

1

Assuming you want S3 to output some function of the values of S1 and S2, here is one way:

s3 = s1.flatMapLatest(function(s1Val) {
    return s2.take(1).map(function(s2Val) {
        return someFunc(s1Val, s2Val);
    });
});

That's a general solution, but there are two simplifications:

If you just want S1's values in S3:

s3 = s1.flatMapLatest(function (s1Val) {
    return s2.take(1).map(s1Val);
});

If you just want S2's values:

s3 = s1.flatMapLatest(s2.take(1));

Example

Here's a copy-paste sample test run from a javascript console, slightly cleaned up to ignore the return values from methods:

s1 = new Bacon.Bus();
s2 = new Bacon.Bus();
someFunc = function(a, b) { return a + b };
s3 = s1.flatMapLatest(function(s1Val) {
    return s2.take(1).map(function(s2Val) {
        return someFunc(s1Val, s2Val);
    });
});
s3.log();
s1.push(1);
s2.push(1);
> VM5993 Bacon-from-git.js:1103 2
s2.push(2);
s2.push(3);
s1.push(2);
s1.push(3);
s2.push(7);
> VM5993 Bacon-from-git.js:1103 10
chreekat
  • 894
  • 7
  • 15
  • but this way `S3` emits every time `S1` does – estolua Dec 29 '14 at 11:13
  • Does it? I added an example test run that seems to produce the behavior you described. – chreekat Dec 30 '14 at 10:28
  • You're right! This was tricky, turns out it doesn't work when `S1` and `S2` are properties, and even with `.toEventStream()` it didn't work, I also had to do `.skipDuplicates()` even though `.log()` didn't show any duplicates. And since I'm not interested in the values involved (only the timing) I used your simplest version `s1.flatMapLatest(s2.take(1))` which also doesn't work with your example, it only emits once. But the other two work fine. I think there might be a bug involved here... – estolua Jan 04 '15 at 13:37