问题可能不是我刚接触rxjs的最佳原因。我事先表示歉意。
this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((queryParams) => {
this.one();
this.two();
});
this.route.queryParams.pipe(first(), takeUntil(this.destroy$)).subscribe((queryParams) => {
this.three();
});
是否有可能将这两个可观察物合而为一?
this.three
仅需触发一次,因为使用了first
运算符。
答案 0 :(得分:2)
如果需要发射值来进行某些控制,则可以使用 combineLatest 以这种方式组合可观察对象:
combineLatest([observable1$, observable2$]).subscribe(([val1, val2]) => {})
当您的任何一个观测值发出一个值时,CombineLatest将发出每个值的最后一个值,或者您可以使用 merge 来获取单个观测值
答案 1 :(得分:0)
您可以使用合并来实现:
const queryParams$ = this.route.queryParams.pipe(share());
const executeOthers$ = queryParams$.pipe(
tap(() => {
this.one();
this.two();
})
);
const executeThree$ = queryParams$.pipe(
first(),
tap(() => this.three())
);
merge(executeOthers$, executeThree$).pipe(
takeUntil(this.destroy$)
).subscribe();
这样做,您确保在第一个queryParams发射上执行了three()方法。每次更改路线参数时,都会首先执行其他两种方法(一种和两种)。
答案 2 :(得分:0)
最干净的解决方案可能只订阅两次。
如果您确实希望将两者结合起来,我会这样做:
this.route.queryParams.pipe(
takeUntil(this.destroy$),
map((value, index) => ({value, index})),
).subscribe(({value: queryParams, index}) => {
if(index === 0){
this.three();
}
this.one();
this.two();
});
这会在流的末尾添加一个索引,因此您可以知道已经发出了多少个值并使用它执行一些逻辑。
另一种解决方案是基本上tap
为第一个值。由于tap
不能为我们提供索引,因此我们可以使用map
并通过不变的方式传递值。
this.route.queryParams.pipe(
takeUntil(this.destroy$),
map((value, index) => {
if(index === 0) this.three();
return value;
}),
).subscribe(queryParams => {
this.one();
this.two();
});
另一种解决方案是创建一个布尔值,以跟踪您是否在流中的第一个值上。为此,您基本上需要创建一个自定义运算符。
this.route.queryParams.pipe(
takeUntil(this.destroy$),
o => defer(() => {
let first = true;
return o.pipe(
tap(val => {
if(first){
this.three();
first = false;
}
})
)
}),
).subscribe(queryParams => {
this.one();
this.two();
});