Как справиться с зависимой подпиской на вызов службы http операторами RxJs? - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть функция с именем fetchSeviceProviders, которая возвращает мне список поставщиков услуг и позволяет мне установить логотип поставщиков услуг путем вызова другой службы.Я добился этого с помощью двух подписок.

При первой подписке я получаю список.Затем я сопоставляю его и вызываю fetchServiceProviderLogo по идентификатору всех поставщиков услуг.

Можно ли это сделать с помощью одной подписки?Мой метод в порядке?Если нет, то в чем проблема?Как я могу сделать это некоторыми операторами rxjs?

Я попробовал оператор map и flatMap, но не смог понять.

fetchServiceProviders ()
{
    this.subscribers.fetchServiceProvidersLogoSub = this.serviceProviderService.fetchServiceProviders( new Map() ).subscribe(
        data =>
        {
            this.providers = data._embedded.serviceProviders;
            this.providers.map(
                provider =>
                {  
                    this.subscribers.fetchServiceProvidersLogoSub =
                        this.serviceProviderService.fetchServiceProviderLogo( { 'id': provider.id } ).subscribe(
                            logo =>
                            {
                                this.createIndividualLogoFromBlob( provider, logo );
                            }
                        );
                }
            );
        }
    )
}

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Если все ваши Наблюдаемые завершены и заказ в этом this.serviceProviderService.fetchServiceProviderLogo вызван, не имеет значения, вы можете использовать комбинацию switchMap (или mergeMap) и merge.Вам также не нужно отписываться, если все ваши запросы на выборку завершены.

fetchServiceProviders () {
  this.serviceProviderService.fetchServiceProviders(new Map())
    .pipe(
      map(data => data._embedded.serviceProviders),
      mergeMap(providers => merge(
        providers.map(provider =>
          this.serviceProviderService.fetchServiceProviderLogo({ 'id': provider.id })
           .pipe(map(logo => ({ provider, logo })))
        )
      ))
    )
    .subscribe(({ provider, logo }) => this.createIndividualLogoFromBlob(provider, logo));
}

Вместо merge вы можете использовать forkJoin для параллельного выполнения вызовов this.serviceProviderService.fetchServiceProviderLogo.

fetchServiceProviders () {
  this.serviceProviderService.fetchServiceProviders(new Map())
    .pipe(
      map(data => data._embedded.serviceProviders),
      mergeMap(providers => forkJoin(
        providers.map(provider =>
          this.serviceProviderService.fetchServiceProviderLogo({ 'id': provider.id })
           .pipe(map(logo => ({ provider, logo })))
        )
      ))
    )
    .subscribe(providerLogos =>
       providerLogos.forEach(({ provider, logo }) => this.createIndividualLogoFromBlob(provider, logo))
    );
}
0 голосов
/ 19 февраля 2019

Вот простой пример.Вы можете считать getItems и getStreetNameById вашими провайдерами.

import { of, from } from 'rxjs';
import { switchMap, groupBy, map, mergeMap } from 'rxjs/operators';

function getItems() {
  return of([
    { streetId: 1, person: 'Person 1' },
    { streetId: 2, person: 'Person 2' },
    { streetId: 1, person: 'Person 3' },
  ]);
}

function getStreetNameById(id: number) {
  console.log('requesting street name for ', id);
  return of('Street ' + id);
}

getItems().pipe( //get all the items
  switchMap(items => from(items)), //create a new stream with each item from the list
  groupBy(item => item.streetId), //group by the streetId (we want to request the street name once per id
  mergeMap(group => { //merge all the transformed groups back into one stream
    return getStreetNameById(group.key) //request the street name by id
      .pipe(
        switchMap(streetName => group.pipe( //merge the street name back to all the items in the group
          map(item => ({ ...item, streetName })),
        ))
      );
  })
).subscribe(items => {
  console.log(items); //now all the items have the street name
});

https://stackblitz.com/edit/rxjs-merge-providers?file=index.ts

0 голосов
/ 19 февраля 2019

В своем коде вы оформляете подписку на каждый сервис-провайдер.Если вы хотите сделать все сразу, вы можете взглянуть на оператор слияния: https://www.learnrxjs.io/operators/combination/merge.html

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