Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why there are no result after CombineLatest like this? #3574

Closed
mimoning opened this issue Apr 16, 2018 · 7 comments
Closed

Why there are no result after CombineLatest like this? #3574

mimoning opened this issue Apr 16, 2018 · 7 comments

Comments

@mimoning
Copy link

Just like demo2, I don't know what's the difference between demo1 and demo2? Why there is no result by demo2?

RxJS version:
5.3.0

Code to reproduce:
demo1:

const a$ = new Rx.BehaviorSubject(1);
const b$ = new Rx.Subject();
b$.combineLatest(a$).subscribe(console.log);
b$.next(1);

demo2:

const a$ = new Rx.BehaviorSubject(1);
const b$ = new Rx.Subject().combineLatest(a$);
b$.subscribe(console.log);
b$.next(1);

Expected behavior:
demo1: [1,1]
demo2: [1,1]

Actual behavior:
demo1: [1,1]
demo2: nothing

Additional information:

@ibedard16
Copy link

ibedard16 commented Apr 16, 2018

Shouldn't b$ be an observable, since it's being set to the return result of combineLatest()?

You may need to do something like

const b$ = new Subject();
b$.combineLatest(a$).subscribe(console.log);

Or, with the new pipeable operators:

const b$ = new Subject();
b$.pipe(combineLatest(a$)).subscribe(console.log);

In order for the call to b$.next() to work.

@mimoning
Copy link
Author

I think you are talking about the thing what demo1 did. @ibedard16
But my point is, why they are different?

@ibedard16
Copy link

The second example is different because b$ is set to the return value of combineLatest() in the second example - which is an observable, not a subject. So, the b$.next() call doesn't actually do anything - it even generates a type error when using rxjs with Typescript.

In order for combineLatest() to fire, all of the observables provided to it need to have fired at least once. In the second example, the Subject() never emits anything - so anything watching the b$ observable will never fire.

@mimoning
Copy link
Author

OK, Thank you very much! I got your point! @ibedard16

@cartant
Copy link
Collaborator

cartant commented Apr 18, 2018

Actually, the problem is rather subtle and I'd say it's a bug, but perhaps not a particularly high-priority one.

Subject implements lift so the return value from the combineLatest operator will actually be a Subject instance - it's just that this cannot be represented with the TypeScript types.

With this code:

const a$ = new Rx.BehaviorSubject(1);
const b$ = new Rx.Subject().combineLatest(a$);
console.log(`b$ instanceof Rx.Subject = ${b$ instanceof Rx.Subject}`);
b$.subscribe(console.log);
b$.next(1);

the output will be:

b$ instanceof Rx.Subject = true

So b$ is a Subject and next can be called.

If you look at the implementation of Subject.lift, you'll see that an AnonymousSubject is returned. Note that this is passed to the AnonymousSubject constructor as the destination.

The implementation of AnonymousSubject.next calls destination.next if it's defined. Otherwise, it does nothing.

The problem is effected because the implementation of combineLatest doesn't pass the source - the Subject - as the context for the lift call; it passes another observable and that observable has no next method, so nothing happens when next is called.

Not all operators are implemented this way. For example, if the delay operator is used instead, it will work as you'd expect. The following will write 1 to the console:

const c$ = new Rx.Subject().delay(0);
c$.subscribe(console.log);
c$.next(1);

@mimoning
Copy link
Author

OK, I understand. It seems that I need to learn more about the internal implementation of RxJS. Thank you very much! @cartant

@lock
Copy link

lock bot commented Jun 5, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants