将RxJS可观察变量与第一个运算符组合

时间:2020-10-30 10:26:45

标签: angular rxjs

问题可能不是我刚接触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运算符。

3 个答案:

答案 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();
});