Как правильно создать и разрешить Observable of Observables (Rx JS) - PullRequest
0 голосов
/ 14 апреля 2020

В моем приложении Angular есть несколько служб, которые зависят друг от друга. Поэтому я создал карту зависимостей для них. Вот сокращенный пример:

let accountInitialization$: Observable<void>;
let productInitialization$: Observable<void>;

const dependenciesMap = {
  accountService: [],
  productService: [
    accountInitialization$ // There could be one or more dependencies
  ]
}

accountInitialization$ = this.getDependencies(dependenciesMap.accountService)
  .pipe(
    mergeMap(_ => {
      return this.accountService.initialize();
    })
  );

productInitialization$ = this.getDependencies(dependenciesMap.productService)
  .pipe(
    mergeMap(_ => {
      return this.productService.initialize();
    })
  );

accountInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.AccountsInitialized);
});

productInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.ProductsInitialized);
});

forkJoin([accountInitialization$, productInitialization$]).subscribe(
  () => {
    // do some work
  },
  error => {
    console.log(error); // This is where I see the error specified below
  }
);

Таким образом, служба продукта зависит от инициализации службы учетной записи. Функция getDependencies выглядит следующим образом:

private getDependencies(dependencies: Observable<void>[]) {
if (dependencies.length) {
  return forkJoin(dependencies);
}
return EMPTY;

}

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

ОШИБКА TypeError: Вы указали 'undefined', где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable.

Похоже, что .initialize() функции никогда не вызываются ...

Я не уверен, что я ' Я делаю неправильно здесь. Спасибо за любую помощь, спасибо.

1 Ответ

1 голос
/ 14 апреля 2020

Вместо использования forkJoin, вы должны использовать switchMap. Я не уверен, как структурировать это так, как у вас, но что-то вроде этого:

import { switchMap } from 'rxjs/operators';
...
productInitialization$ = this.accountInitialization$.pipe(
  switchMap(accountInitializtion => {
    console.log('account initialization finished with: ', accountInitialization);
    // switch to this observable once complete
    return this.productService.initialize();
  });
)

Для вас это может быть иначе, но посмотрите на concatMap, switchMap, mergeMap на go от одного Observable к другому.

...