ForkJoin 2 BehaviorSubjects

时间:2016-09-27 10:36:11

标签: javascript typescript rxjs reactive-extensions-js

我有两个行为主题流我正在尝试forkJoin没有运气。 正如我想象的那样,它会回馈它的最后两个值。这有可能以某种方式实现吗?

在主题之后不会调用它。

let stream1 = new BehaviorSubject(2);
let stream2 = new BehaviorSubject('two');

Observable.forkJoin(stream1, stream2)
    .subscribe(r => {
         console.log(r);
    });

3 个答案:

答案 0 :(得分:11)

请注意forkJoin()在其文档中实际执行的操作:

  

等待Observables完成,然后组合它们发出的最后一个值。

这意味着当{strong>所有输入Observable 完成时,forkJoin()会发出一个值。使用BehaviorSubject时,这意味着在两者上明确调用complete()

import { Observable, BehaviorSubject, forkJoin } from 'rxjs';

const stream1 = new BehaviorSubject(2);
const stream2 = new BehaviorSubject('two');

forkJoin(stream1, stream2)
  .subscribe(r => {
    console.log(r);
  });

stream1.complete();
stream2.complete();

查看现场演示:https://stackblitz.com/edit/rxjs-9nqtx6

2019年3月:更新了RxJS 6。

答案 1 :(得分:9)

如果您不想(或不知道何时)呼叫complete(),则可以使用combineLatest而不是forkJoin

使用combineLatest,只要源可观察对象之一(在您的情况下为行为主体)发出一个值,combineLatest就会触发:

let stream1 = new BehaviorSubject(2);
let stream2 = new BehaviorSubject('two');

combineLatest(stream1, stream2)
    .subscribe(r => {
         console.log(r);
    });

stream1.next(3);
stream2.next('three');

控制台日志:

(2)[2,“两个”] //初始状态

(2)[3,“两个”] //接下来在stream1上触发

(2)[3,“三个”] //接下来在stream2上触发

实时演示:https://stackblitz.com/edit/rxjs-qzxo3n

答案 2 :(得分:1)

您可以使用上面提到的 take(1) 管道或 complete() 方法。

private subjectStream1 = new BehaviorSubject(null);
stream1$: Observable = this.subjectStream1.asObservable();

private subjectStream2 = new BehaviorSubject(null);
stream2$: Observable = this.subjectStream2.asObservable();

forkJoin({
  stream1: this.stream1$.pipe(take(1)),
  stream2: this.stream2$.pipe(take(1))
})
.pipe(takeUntil(this._destroyed$))
.subscribe(values) => console.log(values));