[英]Combine RxJS observables with first operator
这个问题可能不是最好的,因为我是 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();
});
是否有可能将这两个 observable 合二为一? this.three
需要触发一次,因为使用了first
运算符。
如果您需要发出的值来进行一些控制,您可以使用combineLatest以这种方式组合可观察对象:
combineLatest([observable1$, observable2$]).subscribe(([val1, val2]) => {})
当您的任何 observable 发出一个值 combineLatest 将发出每个的最后一个值,或者您可以使用merge来获取单个 observable
您可以使用合并来做到这一点:
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() 方法。 其他两种方法(一种和两种)将首先执行,并且每次更改路由参数时都会执行。
最干净的解决方案可能只订阅两次。
如果您确实更喜欢将两者结合起来,我会这样做:
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();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.