RxJS: чистый способ передачи данных по наблюдаемым цепочкам? - PullRequest
1 голос
/ 06 июня 2019

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

Ниже приведены 3 способа сделать это на простом примере, но ни один из них не похож на способ "RxJS". Есть ли лучший способ сделать это?

// Method #1 - looks clean, but feels hacky

let firstResponse = null;
performFirstAction().pipe(
  tap(_firstResponse => (firstResponse = _firstResponse)),
  switchMap(_firstResponse => performSecondAction(_firstResponse)),
  switchMap(secondResponse => performThirdAction(firstResponse, secondResponse))
);

// Method #2 - gets ugly real quick as it scales

performFirstAction().pipe(
  switchMap(firstResponse =>
    performSecondAction(firstResponse).pipe(
      map(secondResponse => ({ firstResponse, secondResponse }))
    )
  ),
  switchMap(({ firstResponse, secondResponse }) =>
    performThirdAction(firstResponse, secondResponse)
  )
);

// Method #3 - might as well just use callbacks at this point

performFirstAction().pipe(
  switchMap(firstResponse =>
    performSecondAction(firstResponse).pipe(
      switchMap(secondResponse =>
        performThirdAction(firstResponse, secondResponse)
      )
    )
  )
);

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Самый простой и понятный способ сделать это - сохранить промежуточные наблюдаемые в их собственных переменных .

const firstResponse$ = performFirstAction();

const secondResponse$ = firstResponse$.pipe(
  switchMap(firstResponse => performSecondAction(firstResponse)),
);

const thirdResponse$ = secondResponse$.pipe(
  withLatestFrom(firstResponse$),
  switchMap((secondResponse, firstResponse) => performThirdAction(firstResponse, secondResponse))
);
0 голосов
/ 06 июня 2019

есть другой подход для вашего сценария

performFirstAction().pipe(
  switchMap(first =>
    performSecondAction(first).pipe(mergeMap(second=>performThirdAction(first, second)))
    )
  ),
);

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

и если вам нужен общий шаблон, попробуйте mergeScan, создав функцию более высокого порядка для возврата к наблюдаемой.Здесь acc всегда является последним наблюдаемым возвращаемым значением

from([first,first=>second(first),second=>third(second)])
.pipe(mergeScan((acc,currObs)=>currObs(acc),null))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...