Цепочка наблюдаемых Angular 5 / Rxjs

Я немного запутался с операторами rxjs. У меня есть несколько вызовов API, которые возвращают наблюдаемые:

getCurrentUser(): Observable<any> {
    return this.http.get<any>(userUrl);
  }

tagsList(): Observable<string[]> {
    return this.http.get<string[]>(tagsUrl);
  }

timezonesList(): Observable<Timezone[]> {
    return this.http.get<Timezone[]>(timezonesUrl);
  }

Я хочу вызвать getCurrentUser(), затем с результатом возвращаемого значения действия вызова LoadUser(user) Затем, после того, как пользователь загрузит вызов нескольких асинхронных запросов одновременно:

tagsList(), timezonesList()

А затем с результатами возврата их значения вызывают действия LoadTags(tags), LoadTimezones(timezones)

Таким образом, это должно выглядеть примерно так:

init() {
  this.accountsApi.getCurrentUser()
      .map((user: User) => this.store.dispatch(new LoadUser({ user })))
      .map(
        this.commonApi.tagsList(),
        this.commonApi.timezonesList(),
        this.commonApi.authoriztionServicesList()
      )
      .map((tags, timezones, authorizationServices) => {
        this.store.dispatch(new tagsActions.LoadTags(tags));
        this.store.dispatch(new timezonesActions.LoadTimezones(timezones));
        this.store.dispatch(new authorizationServicesActions.LoadAuthorizationServices(authorizationServices));
      });
}

Я знаю, что эти операторы ошибаются. Какие операторы я должен использовать для этого? Я уже сделал это с промисами, но я уверен, что смогу сделать это с операторами rxjs с меньшим количеством строк кода.

P.S. Также мне интересно, как я могу сделать это с помощью async/await? Спасибо


person mr__brainwash    schedule 15.05.2018    source источник
comment
Каким должен быть возвращаемый тип init()?   -  person a better oliver    schedule 16.05.2018
comment
Это не имеет значения. На самом деле return не нужен. Я обновил вопрос и удалил return   -  person mr__brainwash    schedule 16.05.2018


Ответы (1)


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

init() {
  return this.accountsApi.getCurrentUser()
      .do((user: User) => this.store.dispatch(new LoadUser({ user })))
      .forkJoin(
        this.commonApi.tagsList(),
        this.commonApi.timezonesList(),
        this.commonApi.authoriztionServicesList()
      )
      .do((results) => {
        this.store.dispatch(new tagsActions.LoadTags(results[0]));
        this.store.dispatch(new timezonesActions.LoadTimezones(results[1]));
        this.store.dispatch(new authorizationServicesActions.LoadAuthorizationServices(results[2]));
      });
}

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

Оператор do вводит побочные эффекты для запуска действий вашего магазина, поскольку вы не хотите создавать какие-либо массивы.

person Mike Tung    schedule 15.05.2018
comment
Спасибо, я знаю слишком много карт, я написал это просто для примера, потому что я не знаю, какие операторы мне там использовать. Но можно ли это сделать без array[index]? Как-то справиться с интерфейсами возврата значений вызовов commonApi? Как я написал в своем последнем примере кода - person mr__brainwash; 15.05.2018