Правильный способ передачи данных от одного наблюдаемого к другому - PullRequest
0 голосов
/ 05 июля 2018

У меня есть два HTTP API -

  1. Получает список имен таблиц
  2. Получает список метаданных

Я работаю над приложением Angular 5, в котором метаданные (из 2-го API) перед отображением необходимо изменить, используя имена таблиц (из 1-го API).

Поэтому я вижу задачу следующим образом -
У меня есть две наблюдаемые. Первая наблюдаемая подключается к tableNames API и возвращает tableNames. Вторая наблюдаемая подключается к metadata API, приносит метаданные и модифицирует метаданные в соответствии с выводом tableNames API. Я хотел бы сохранить конечный продукт (измененные метаданные) в качестве наблюдаемой, на которую может подписаться угловое приложение.

В настоящее время код выглядит в данный момент примерно так:

private tablesNames: ReadonlyArray<String> | undefined;

this.getTablesNamesObservable().subscribe(
      tablesNames => { this.tablesNames = tablesNames; }
    );

// modify metadata uses tableNames to modify the metadata
this.modifiedMetadataObservable = this.metadataService.getOperatorMetadata()
                                      .map(metadata => this.modifyMetadata(metadata));

Мне не понравилось в коде, так как я предполагал синхронизацию между двумя асинхронными операциями. Сомнение было доказано сразу после прочтения этой статьи . Итак, используя подход, предложенный в статье, я изменил код, чтобы в качестве параметра для создания новых Observables указывал tableNames и использовал switchMap (я мог бы использовать concatMap / flatMap, но switchMap соответствовал моим требованиям).

this.getTablesNamesObservable().switchMap(
      tableNames =>{this.metadataService.getOperatorMetadata()
                        .map(metadata => this.modifyMetadata(metadata, tableNames));}
      );

Это правильный путь для выполнения этой задачи или есть другие лучшие методы для достижения этой цели?

1 Ответ

0 голосов
/ 05 июля 2018

Если getTablesNamesObservable и getOperatorMetadata независимы, имеет смысл использовать combineLatest:

Observable.combineLatest(
  this.getTablesNamesObservable(),
  this.metadataService.getOperatorMetadata()
).map(([tableNames, metadata]) => this.modifyMetadata(metadata, tableNames));

Тогда modifyMetadata будет вызываться всякий раз, когда какое-либо наблюдаемое излучает значение.

Используя switchMap, вы отписываетесь и повторно подписываетесь на наблюдаемое, возвращаемое getOperatorMetadata всякий раз, когда наблюдаемое, возвращаемое getTablesNamesObservable, испускает. И если они независимы - то есть getOperatorMetadata не нужно передавать имена таблиц - делать do кажется ненужным.

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

...