RxJS Вывод массива подписки из нескольких mergeMap - PullRequest
0 голосов
/ 15 июня 2019

Мне было интересно, можно ли вывести массив, наблюдаемый после нескольких вызовов mergeMap

Вот пример того, что я хотел бы получить

 this.kbSvc.create(kb).pipe(
            map(dbKb => kb = dbKb),
            mergeMap(() => this.goSvc.create(kb.id, "Build Market Share")),
            mergeMap(go => this.marketSvc.create(kb.id, (<GrowthOpportunity>go).id, "Market Segment - TBD")),
            mergeMap(ms => this.companySvc.create({ id: kb.id, msId: (<MarketSegment>ms).id }, "Company Type - TBD")),
        ).subscribe(([goSvc Result, marketSvc Result, companySvc Result]) => // //);

Всезвонки выше зависят друг от друга, потому что я не могу использовать forkJoin.Другими словами, моя предыдущая наблюдаемая должна завершиться до вызова новой.

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

Спасибо!

Ответы [ 2 ]

1 голос
/ 15 июня 2019

Операторы, с которыми я сталкивался до сих пор, не поддерживают состояние полученных или отправленных значений.Как и поток воды, они просто позволяют потоку данных изменяться так, как они хотят.

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

Давайте для ясности определим все ваши наблюдаемые под функцией.

goFunc(id) {
  return this.goSvc.create(id, "Build Market Share");
}

marketFunc(id, goData) {
  return this.marketSvc.create(id, (<GrowthOpportunity>goData).id, "Market Segment - TBD");
}

companyFunc(id, msData) {
  return this.companySvc.create({ id: id, msId: (<MarketSegment>msData).id }, "Company Type - TBD");
}

Вот функция для вложенного трубопровода,

 someFunc() {

 this.kbSvc.create(kb).pipe(
  mergeMap(kb => this.goFunc(kb).pipe(
    mergeMap(goData => this.marketFunc(kb,goData).pipe(
      mergeMap(msData => this.companyFunc(kb,msData).pipe(
        map((companyData) => [goData,msData,companyData])
      )),
    ))
  ))
 ).subscribe(data => {
  //data will have [goData,msData,companyData]
  console.log(data);
 });

}

Это должно дать ожидаемый результат.

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

Одним из вариантов может быть использование combineLatest следующим образом -

this.kbSvc
        .create(kb)
        .pipe(
                map(dbKb => kb = dbKb),
                mergeMap(() => this.goSvc.create(kb.id, "Build Market Share")),
                mergeMap(go => {

                  return combinedLatest(of(go), this.marketSvc.create(kb.id, (<GrowthOpportunity>go).id, "Market Segment - TBD"));

                }),
                mergeMap(([goSvcResult, marketSvcResult]) => {
                  return combinedLatest(of([goSvcResult, marketSvcResult]), this.companySvc.create({ id: kb.id, msId: (<MarketSegment>marketSvcResult).id }, "Company Type - TBD"));
                })

        ).subscribe(([[goSvc Result, marketSvc Result], companySvc Result]) => // //);

Обратите внимание на входной сигнал обратного вызова подписки.Хотя это не совсем то, что вы ожидаете, все же это почти то же самое.

...