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 ... )