RxJS如何在继续之前等待两个ReplaySubjects生成值

时间:2016-11-15 01:26:22

标签: rxjs observable

我想用于这样的连接:

Observable.forkJoin(
    this.service1.dataSourceIsAReplaySubject,
    this.service2.dataSourceIsAnObservable)
.subscribe(values => {
    console.log('inside subscribe values is', values);
});

但是console.log永远不会触发。

我猜测重播主题永远不会完成,这就是为什么forkJoin永远不会停止等待。

我试过这个,但这也行不通。 我首先尝试了ReplaySubject,然后尝试了Observable,反之亦然。

Observable.forkJoin(
    Observable.from(this.service1.dataSourceIsAReplaySubject),
    this.service2.dataSourceIsAnObservable)
.subscribe(values => {
    console.log('inside subscribe values is', values);
});

我也试过调用share方法:

Observable.forkJoin(
    this.service1.dataSourceIsAReplaySubject.share(),
    this.service2.dataSourceIsAnObservable)
.subscribe(values => {
    console.log('inside subscribe values is', values);
});

我可以做什么来等待两个ReplaySubjects或1个ReplaySubject和1个Observable的混合

2 个答案:

答案 0 :(得分:8)

正如您自己所说,问题是forkJoin仅在所有流完成后才会发出。如果您打算使用它,则需要确保所有流以某种方式完成(first()take(1)等等。)。

更好的选择可能是根据您的需要使用zipcombineLatest。实现看起来类似:

Observable.zip(
    this.service1.dataSourceIsAReplaySubject,
    this.service2.dataSourceIsAnObservable
).subscribe(values => {
    console.log('inside subscribe values is', values);
});

// OR

Observable.combineLatest(
    this.service1.dataSourceIsAReplaySubject,
    this.service2.dataSourceIsAnObservable
).subscribe(values => {
    console.log('inside subscribe values is', values);
});

<强>击穿

zip会相互锁定两个Observable,也就是每次发出一个,另一个也必须在zip发出一个值之前发出,虽然这很有用但是如果一个比另一个更快地发出(因为它会导致无限制的缓冲区在幕后发展)。

combineLatest将等到两个流都发送至少一次,然后任何时候发出,combineLatest将使用最新的另一个流发出。

还有第三种选择,称为withLatestFrom。它的功能类似于combineLatest,但只有在第一个流发出并静默更新所有其他最新值而不发出时才会发出警告。

答案 1 :(得分:4)

forkJoin在传递给它的observable完成之前不会发出值;它会发出每个可观察数据的最后值。

您可以使用first运算符确保它们完整:

Observable.forkJoin(
    this.service1.dataSourceIsAReplaySubject.first(),
    this.service2.dataSourceIsAnObservable.first())
.subscribe(values => {
    console.log('inside subscribe values is', values);
});