问题
Looking at the definition of combineLatest
Combines multiple Observables to create an Observable whose values are calculated from the latest values of each of its input Observables.
or
Whenever any input Observable emits a value, it computes a formula using the latest values from all the inputs, then emits the output of that formula.
It's pretty clear to see that at each period of time / emission , the result at that emission is the combination of the latest emissions.
If so , looking at this code
const obs1 = Rx.Observable.of(1, 2, 3, 4, 5);
const obs2 = Rx.Observable.of('a', 'b', 'c')
const obs3 = obs2.combineLatest(obs1, (a, b) => a+b);
const subscribe = obs3.subscribe(latestValues => {
console.log(latestValues );
});
The result is :
c1,c2,c3,c4,c5
And when I change
obs2.combineLatest(obs1..
to
obs1.combineLatest(obs2..
— I get 5a,5b,5c
Question:
The docs don't specify any difference regarding the order of invocation (if so - why do I get different results) ?
Why don't I see other combinations with the other source ? It seems that one source is taking its last value and only then - join it to each value from the OTHER source.
It seems like that this is what actually happening:
[other source]---a---b---c------------------------
[first source]-------------1----2-----3-----4----5
[result]-------------------c1---c2----c3----c4---c5
And when I swap the order (obs1<->obs2) :
[first source]-----1--2---3--4--5----------------
[other source]---------------------a-----b------c
[result]---------------------------5a----5b-----5c
What's going on here? why does one stream has to finish in order for the join to start ?
Why don't I see something like this ( or a variation) :
[first source]-----1-----2--------3-------4------5---
[other source]---------a-----b------c----------------
[result]---------------1a------2b------3b---4c-------5c
JSBIN
回答1:
This is because values from your source Observables are emited synchronously unless you use a Scheduler. This means that first obs1
emits all values and only the last one is remembered by combineLatest
and than obs2
starts emiting all its values (the same appplies if you switch the two Observables). Now the combineLatest
has values for both Observables so any emission from the second Observables will make the operator emit a value.
Why it works like this is because Observable.of
is implemented as ArrayObservable
internally and by default it doesn't use any Scheduler. This means that all its emissions happen synchronously. See https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts#L118
Btw, you can add Rx.Scheduler.async
as the last parameter to both source Observables.
来源:https://stackoverflow.com/questions/43620219/combinelatest-behaviour-in-rxjs-5