Angular - RxJS - Как выполнить действия для отфильтрованных элементов в цепочке?

У меня есть труба, как это:

this.parentFormControl.valueChanges
  .pipe(
    debounceTime(500),
    distinctUntilChanged(),
    tap(() => {
      this.focusIndex = -1;
    }),
    filter(() => this.myCondition()),
    switchMap((value: string) => {
      return this.http.get(value).pipe(catchError(err => {
        this.myErrorFunction(err);
        return EMPTY;
      }));
    })
  )

И я хотел бы выполнить некоторые другие "побочные" действия, такие как оператор tap, для элементов, которые фильтруются -removed- (который возвратил "false" из "myCondition()", так сказать) Как мне это сделать?

3 ответа

Вы можете разделить цепочку используя multicast а затем добавить tap для обоих условий и после этого просто игнорируйте результаты, которые вам не нужны:

range(1, 10)
  .pipe(
    multicast(() => new Subject(),
      o => merge(
        o.pipe(
          filter(v => v % 2 === 0),
          tap(v => console.log('true', v)),
        ),
        o.pipe(
          filter(v => v % 2 !== 0),
          tap(v => console.log('false', v)),
          ignoreElements(),
        ),
      )
    ),
  )
  .subscribe(v => console.log('result', v));

Это немного долго, но это правильно разделяет источник на две цепочки.

Демонстрационная версия: https://stackblitz.com/edit/rxjs6-demo-yarhux?file=index.ts

Вы можете добавить условие для проверки в вашем кране перед фильтром.

this.parentFormControl.valueChanges
  .pipe(
    debounceTime(500),
    distinctUntilChanged(),
    tap((x) => {
      this.focusIndex = -1;
      if (!this.myCondition()) console.log(x); // here
    }),
    filter(() => this.myCondition()),
    switchMap((value: string) => {
      return this.http.get(value).pipe(catchError(err => {
        this.myErrorFunction(err);
        return EMPTY;
      }));
    })
  )

я хотел бы использовать partition(https://rxjs.dev/api/index/function/partition), чтобы разделить ваш поток на результат фильтрации и то, что было отфильтровано.

      const [result$, filteredOut$] = partition(source, (value) => myCondition(value));

// Observable w/ everything filtered out
result$.pipe( ... business as usual ... )

// Observable w/ what was filtered out
filteredOut$.pipe( ... taps, etc ... )
Другие вопросы по тегам