В основном вам нужен один источник с действиями. Тема - хороший способ сделать это.
Затем вы хотите выполнить некоторую обработку для каждого типа действия. Вы можете filter
и subscribe
для каждого подпотока.
const add$ = source.pipe(filter(a => a.type === "add")).subscribe(function onAddAction(a) {});
const remove$ = source.pipe(filter(a => a.type === "remove")).subscribe(function onRemove(a) {});
Или вы можете подготовить подпотоки, а затем снова объединить их со всеми обработанными действиями.
const add$ = source.pipe(filter(a => a.type === "add"), tap(onAdd));
const remove$ = source.pipe(filter(a => a.type === "remove"), tap(onRemove));
const processedAction$ = merge(add$, remove$);
processedAction$.subscribe(logAction);
Если вам нужно выполнить некоторую предварительную обработку всех действий, вы можете использовать share
или shareReplay
. toAction
будет вызываться только один раз за каждый элемент.
const subject = new Subject();
const action$ = subject.pipe(map(toAction), share());
const add$ = action$.pipe(filter(isAdd));
...
merge(add$, remove$).subscribe(logAction);
А если у вас проблемы с разбиением:
function not(predicate) {
return function(item, ...args) {
return !predicate(item, ...args);
}
}
function any(...predicates) {
return function(item, ...args) {
return predicates.some(p => p(item, ...args));
}
}
const a = source.pipe(filter(fa), map(doA));
const b = source.pipe(filter(fb), map(doB));
const c = source.pipe(filter(fc), map(doC));
const rest = source.pipe(filter(not(any(fa, fb, fc)));
merge(a, b, c, rest).subscribe(logAction);