Сцепление наблюдаемых с flatMap

1

im работает с наблюдаемыми и оператором flatMap, я написал метод, который вызывает и вызывает API и возвращает наблюдаемый массив массивов. В основном мне нужно получить этот массив объектов и обрабатывать каждый объект, после того как все элементы обработаны. Я хочу связать результат, чтобы сделать дополнительный вызов API другим методом, который я написал. Следующий код делает то, что мне нужно:

  this.apiService.getInformation('api-query', null).first().flatMap((apiData) => {
    return apiData;
  }).subscribe((dataObject) => {
    this.processService.processFirstCall(dataObject);
  }, null, () => {
    this.apiService.getInformation('another-query', null).first().subscribe((anotherQueryData) => {
      this.processService.processSecondCall(anotherQueryData);
    });
  });

Но этот подход не является оптимальным с моей точки зрения, я хотел бы сделать цепочку этих вызовов с помощью flatMap, но если я сделаю следующее

   this.apiService.getInformation('api-query', null).first().flatMap((apiData) => {
    return apiData;
  }).flatMap((dataObject) => {
    this.processService.processFirstCall(dataObject);
    return [dataObject];
  }).flatMap((value) => {
    return this.apiService.getInformation('another-api-query', null).first();
  }).subscribe((value) => {
    this.processService.processSecondCall(value);
  });

Второй вызов API выполняется один раз для каждого элемента массива apiData. Я знаю, что упускаю или что-то недопонимаю. Но со второго ответа этой темы. Почему нам нужно использовать flatMap? Я думаю, что вторая flatMap должна возвращать обработанную apiData, вместо этого возвращает каждый из объектов объекта в этом массиве. Я был бы признателен за помощь.

Спасибо.

Теги:
angular
rxjs
observable

2 ответа

4

Вам нужен оператор .do(), а не flatMap(). flatMap() преобразует событие в другое событие и, по сути, связывает его. .do() просто выполняет все, что вы ему поручаете, каждой эмиссии в событиях.

Из вашего кода есть 2 асинхронных метода (вызовы api) и 2 синхронных (processService). Что вы хотите сделать:

  1. Вызовите первый API (async), дождитесь результатов
  2. Обработать результаты (синхронизация)
  3. Позвоните во второй API (async), дождитесь, пока результаты вернутся.
  4. Обработать результаты (синхронизация)

Следовательно, ваш код должен быть:

this.apiService.getInformation('api-query', null)//step1
    .first()
    .do((dataObject) => this.processFirstCall(dataObject))//step2
    .flatMap(() => this.apiService.getInformation('another-api-query', null))//step3
    .first()
    .do(value => this.processService.processSecondCall(value))//step4
    .subscribe((value) => {
        console.log(value);
    });

Я написал в комментарии шаги, соответствующие приведенному выше списку. Я также очистил ненужных операторов (например, ваш первый flatMap является избыточным).

Кроме того, в случае, если вы хотите преобразовать свои данные, вы должны использовать .map() вместо .do(). И я думаю, что это то место, где вас путают с .map() и .flatMap().

0

Проблема, я думаю, что ваша встреча заключается в том, что план должен применяться к наблюдаемому или обещаемому. в вашем втором примере кода вы возвращаете данные в оператор flatmap, который затем передается следующим функциям flatmap, тогда как они должны возвращать наблюдаемые. Например:

this.apiService.getInformation('api-query', null).first()
  .flatMap((dataObject) => {
    return this.processService.processFirstCall(dataObject);
  }).flatMap((value) => {
    return this.apiService.getInformation('another-api-query', null)
  }).subscribe((value) => {
    this.processService.processSecondCall(value);
  });

См. Это сообщение для дальнейшего уточнения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню