[英]Combine RxJS observables with first operator
The question might no be the best cause I'm new to rxjs.这个问题可能不是最好的,因为我是 rxjs 的新手。 I apologize in advance.我提前道歉。
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();
});
Is it possible to combine these two observables into one?是否有可能将这两个 observable 合二为一? this.three
needs to be fired only once, as first
operator is used. this.three
需要触发一次,因为使用了first
运算符。
You can use combineLatest to combine observables that way if you need emitted value to do some control :如果您需要发出的值来进行一些控制,您可以使用combineLatest以这种方式组合可观察对象:
combineLatest([observable1$, observable2$]).subscribe(([val1, val2]) => {})
When any of your observables emits a value combineLatest will emit the last value of each, or you can use merge to get a single observable当您的任何 observable 发出一个值 combineLatest 将发出每个的最后一个值,或者您可以使用merge来获取单个 observable
You could use a merge to do it:您可以使用合并来做到这一点:
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();
By doing so, you make sure that the three() method get executed on the first queryParams emission.通过这样做,您可以确保在第一个 queryParams 发射时执行了 Three() 方法。 The two other methods (one and two) will be executed on first and each time you change your route params.其他两种方法(一种和两种)将首先执行,并且每次更改路由参数时都会执行。
The cleanest solution is likely to just subscribe twice.最干净的解决方案可能只订阅两次。
If you do prefer to combine the two, I would do it like this:如果您确实更喜欢将两者结合起来,我会这样做:
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();
});
This adds an index right at the end of your stream, so you can know how many values have been emitted and use it to perform some logic.这会在流的末尾添加一个索引,因此您可以知道发出了多少个值并使用它来执行某些逻辑。
Another solution is to basically tap
the first value.另一种解决方案是基本上tap
第一个值。 Since tap
doesn't give us an index, we can use map
and pass values through unaltered.由于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();
});
Another solution is to create a boolean that tracks if you're on the first value in a stream or not.另一个解决方案是创建一个布尔值来跟踪您是否在流中的第一个值上。 To do this, you're essentially required to create a custom operator.为此,您基本上需要创建一个自定义运算符。
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.