我有两个行为主题流我正在尝试forkJoin没有运气。 正如我想象的那样,它会回馈它的最后两个值。这有可能以某种方式实现吗?
在主题之后不会调用它。
let stream1 = new BehaviorSubject(2);
let stream2 = new BehaviorSubject('two');
Observable.forkJoin(stream1, stream2)
.subscribe(r => {
console.log(r);
});
答案 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上触发
答案 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));