Лестница RxJs при сцеплении Observable - PullRequest
0 голосов
/ 27 июня 2018

До того, как я использовал Promise с асинхронным / ожидающим синтаксисом в Typescript, выглядел следующим образом

const fooData = await AsyncFooData();
const barData = await AsyncBarData();

... do something with fooData and barData

Если я делаю это с RxJs Observable<T>, это становится для меня чем-то вроде этого

AsyncFooData().subscribe(fooData => {
   AsyncBarData().subscribe(barData => {
      ... do something with fooData and barData
   })
})

Есть ли лучший способ сделать это? Потому что он становится быстро не читаемым, а именно Лестница, если у меня будет больше AsyncData, с которым мне нужно работать.

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Вы не сможете сделать то, что сделали с async / await, так как вам все еще нужен обратный вызов .subscribe, и существует вероятность того, что несколько свойств будут отправлены. Вы должны никогда вкладывать .subscribe звонки. Как правило, вы будете использовать оператор Observable более высокого порядка, например mergeMap, или создатель Observable, который синхронизирует излучение нескольких наблюдаемых вместе, например combineLatest:

combineLatest(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData] => {

});

Точная функция, которая вам нужна, зависит от ваших собственных потребностей, а также от того, как foo и bar излучают:

  • combineLatest - Излучает каждый раз, когда излучает любой источник ( примечание: не начинает излучать, пока все источники не выпустят один раз).
  • zip - Синхронизирует выбросы, например, испускается один раз, когда каждый наблюдаемый испускает один раз, затем дважды и т. д.
  • forkJoin - издает, когда все исходные наблюдаемые завершены
  • merge - Издает каждый раз, когда излучает любой источник. Он не объединяет выходные данные, как другие выше.

Есть еще доступные: https://www.learnrxjs.io/operators/combination/

0 голосов
/ 27 июня 2018

Я думаю, вы пытаетесь найти хороший способ «связать» несколько асинхронных операций «чище». Вот что я делаю:

  • Я использовал from(), как я предполагал AsyncFooData возвращает обещание. Если он возвращает Observable, просто удалите from().
  • избегайте нескольких подписок (обычно реже, чем мы думаем).
  • используйте pipe(), чтобы связать соответствующих операторов, сколько вам нужно, довольно простым способом.
  • subscribe() вызывается, когда все операции выполнены.
  • Стиль Передача результата от foo до следующей функции подписки.
  • Стиль B работает только с результатом последней асинхронной операции.

Примечание. Эти примеры написаны для совместного использования концепции / подхода без проверки синтаксиса IDE. Концепция должна работать, но извинения, если есть синтаксические ошибки.

// A: if you need both foo and bar
from(AsyncFooData()).pipe(
  concatMap(foo => AsyncBarData().pipe(
    map(bar => ({foo, bar})
  )),
  tap(val => console.log(val), // chain more operators here...
).subscribe(({foo, bar}) => {
  // do stuff with foo and bar
})

// B: if foo is only used to get bar (i.e. no need to pass it along)
from(AsyncFooData()).pipe(
  concatMap(foo => AsyncBarData(foo)), // assume foo is only used to get bar
  tap(val => console.log(val), // chain more operators here...
).subscribe(bar => {
  // do stuff with bar
})
0 голосов
/ 27 июня 2018

Вы можете zip и получить fooData и barData и делать все, что хотите.

zip(AsyncFooData(), AsyncBarData()).subscribe([fooData, barData]) => {})

Здесь zip взят в качестве примера. Вы можете использовать других операторов, таких как combineLatest в соответствии с вашими потребностями.

Я воздерживаюсь от объяснения различий между zip и combineLatest и другими операторами здесь, потому что это может загромождать этот ответ. Вместо этого я указываю следующие ресурсы, там все четко объяснено с помощью диаграмм и примеров:

(1) Официальный документ

(2) Мраморные диаграммы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...