Rx JS труба для фильтрации в 2 + ответвления - PullRequest
1 голос
/ 06 февраля 2020

Давайте предположим, что у нас есть субъект, который может возвращать заданный набор значений, каждый из которых может потребовать другого подхода к ним. Мы могли бы обсудить, должно ли это когда-либо иметь место, НО не совсем предмет моего расследования.

Так что ... чтобы справиться с этим, наш код мог бы выглядеть примерно так:

var sub = new Subject(); 

sub.subscribe( 
    data => {
        if (caseA) {
            // do something
        }
        if (caseB) {
            // do something else
        }
     });

, что все отлично и прекрасно ... но мне было интересно, есть ли какой-нибудь оператор что мы можем связать, чтобы сделать его более rx-i sh? Мысль о фильтре, но сцепление caseA и caseB просто не даст ему работать (очевидно), поскольку в итоге происходит фильтрация обоих.

Итак, мой вопрос сводится к следующему: возможно ли иметь что-то отдаленно напоминающее рев псевдокода? Любой оператор (ы) вы знаете, что будет работать так?

var sub = new Subject(); 

sub.pipe(
    magicOperator(//handles caseA),
    magicOperator(//handles caseB),
)
subscribe( 
    data => {
        // handles common thread
     });

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Я думаю, что более rx js способ решения этой проблемы аналогичен тому, что предложил @ritaj, но с помощью оператора слияния stati c для разделенных потоков (или concat, если вы хотите обрабатывать их последовательно)

let sub = new Subject();
// i'm using typescript syntax, but you can refer to them by index
let [leftPartition, rightPartition] = sub.pipe( partition( [predicate] ) )
// apply custom logic to the left and right partition
rightPartition = rightPartition.pipe( map( x => x + 1 ) )
leftPartition = leftPartition.pipe( map( x => x - 1 ) )

merge(
     leftPartition,
     rightPartition
).pipe(
    tap( 
        ( value ) => {
            // this stream consumes both right and left partition outputs
        }
    )
).subscribe();

Оператор разбиения
Объединение (stati c)

Версия объединения stati c импортируется из rx js упакуйте и примите любое количество аргументов (и вы можете даже передать аргументы массива, используя распространение)

Я переназначил наблюдаемую переменную после применения оператора карты. Я не знаю, является ли это хорошей практикой или нет, но ее можно улучшить или разделить на другую переменную, если вам нужен источник без изменений)

Ps. Я обычно стараюсь сохранить обратный вызов подписки свободным от какой-либо реализации, так как большинство вещей, которые вы делаете в конце потока, является побочным эффектом, я помещаю их в оператор tap (те же аргументы, что и подписки)

1 голос
/ 06 февраля 2020

просто создание объекта с функциями переключения регистра может сделать код красивее

const handler={
  case1:()=>..handle case1,
  case2:()=>...handle case2
}

sub.map(result=>handler[result])

// experimental switchCase operator 
const switchCase=handlers=>(source)=>source.map(val=>handlers[val]())

// usage
sub.pipe(switchCase({
   case1:....,
   case2:....
}))
...