question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Non obvious behavior with `concat`, `Promise` and `EventEmitter`.

See original GitHub issue

Hello.

Using xstream on a new project is my only experience with reactive programming so far. Therefore please excuse any obvious problems or mistakes.

I encountered a strange problem with this snippet:

concat(xs.fromPromise(somePromise), fromEvent(someEvent, 'test'));

My expectation was that concat would buffer the test events until the promise resolves (kind of like flattenSequentially. But the events are dropped altogether. I wrote two tests to expose this problem: https://github.com/kaukas/xstream/commit/6e693896c72fda4143d607e2b3996797fb822d62. Could you please let me know if this is expected behavior?

Thank you!

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
kaukascommented, Feb 8, 2017

Hello, @staltz.

I’ve been playing further with this. I am not sure how concat should behave but flattenSequentially is definitely not doing the right thing. Even in the case where the event is sent after the promise resolves the event is lost.

I suspect the reason for the lost events is that the fromEvents stream is only activated after the previous stream (promise) completes. Therefore all prior events are lost. Instead the fromEvents stream should be activated immediately on flattenSequentially call so that all subsequent events could be buffered. At least this is my opinion.

Thank you!

0reactions
webmaster128commented, Jan 3, 2019

I’m implementing a version of buffering concat right now for my project.

This is a test case that shows the difference between the two versions of concat:

  it("buffers asynchonous events of second stream until first stream completes", done => {
    const sourceStream = Stream.periodic(25);
    const stream1 = sourceStream.take(3);
    const stream2 = sourceStream.take(3);
    const concatenatedStream = concat(stream1, stream2);
    const expected = [0, 1, 2, 0, 1, 2];

    concatenatedStream.addListener({
      next: value => expect(value).toEqual(expected.shift()!),
      complete: () => {
        expect(expected.length).toEqual(0);
        done();
      },
      error: done.fail,
    });
  });
  • For buffering concat (see diagram above) it passes
  • For xstream concat it produces [0, 1, 2, 3, 4, 5] instead of [0, 1, 2, 0, 1, 2]

The buffering concat behaves like

--1--2---3---4-|
-a--b-c--d-|
--------X---------Y---------Z-
          concat
--1--2---3---4-abcdXY-------Z-

wheras xstream concat behaves like

--1--2---3---4-|
...............--a-b-c--d-|
          concat
--1--2---3---4---a-b-c--d-|

As far as I can see xstream does what it documents. Hard to say what users expect.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ExpressJS apparent race condition between Promise and ...
The problem is coming from your internal call to busboy inside your handler. Rather than it executing and simply returning control to your ......
Read more >
Ward Bell: Do Not Expect EventEmitter To Be Observable In ...
Promises only ever settle on one value, be it through resolution or rejection. So, in that case - in the case where you...
Read more >
EventEmitter - Angular
Creates an instance of this class that can deliver events synchronously or asynchronously. This class is "final" and should not be extended. See...
Read more >
A thenable should be synchronous? · Issue #5 · getify/native ...
Promise.resolve(2) would obviously be sync, so I'm not sure why the above should be forced to be async if you are handed a...
Read more >
RxJS - Creation Operators - DEV Community ‍ ‍
In this case we converted a promise to an observable. ... Concat unlike of combineLatest does not run all observables in concurrency, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found