在上一篇中介绍了combineLatest的使用,下面我们列出其核心代码实现:
class CombineLatestSubscriber extends OuterSubscriber {
_next(observable) {
this.values.push(none);
this.observables.push(observable);
}
_complete() {
const observables = this.observables;
const len = observables.length;
if (len === 0) {
this.destination.complete();
} else {
this.toRespond = len;
for (let i = 0; i < len; i++) {
const observable = observables[i];
subscribeToResult(this, observable, observable, i);
}
}
}
notifyNext(outerValue, innerValue, outerIndex) {
const values = this.values;
const oldVal = values[outerIndex];
const toRespond = !this.toRespond
? 0
: oldVal === none ? --this.toRespond : this.toRespond;
values[outerIndex] = innerValue;
if (toRespond === 0) {
this.destination.next(values);
}
}
}
export class CombineLatestOperator {
call(subscriber, source) {
return source.subscribe(new CombineLatestSubscriber(subscriber));
}
}
export function higherOrderCombineLatest(observables) {
return source => source.lift.call(new ArrayObservable([source, ...observables]), new CombineLatestOperator());
代码中可以看出:
- CombineLatest操作调用时,会将参数Observable和source Observable创建一个新的Observable,而且该Observable是一个数组。
- ArrayObservable的subscribe方法执行时,会将所有的observable存储在CombineLatestSubscriber的observables变量中
- 执行ArrayObservable的方法_complete,会调用CombineLatestSubscriber的_complete方法,在该方法中会在每个observable emit数据的时候调用notifyNext方法。
- notifyNext中我们可以看到,values数组中存储的是每个observable发射的最新数据,而且只有所有observable都发射过数据,也就是toRespond为0的时候才会执行destination的next方法。