Подпишитесь на несколько обращений в службу последовательно

Мне нужно сделать 2 вызова API, я хочу, чтобы первый вызов завершился, а затем второй вызов начался последовательно. Второй вызов не зависит от первого вызова. оба вызова обновляют БД. если я использую приведенный ниже код, обновление до второго вызова происходит несколько раз, из-за чего он пытается обновить одну и ту же запись несколько раз, чего я хочу избежать. любая помощь приветствуется.

updateUserCommentsObservable(): Observable<any> {
  if (!this.userComments) {
    return EMPTY;
  }

  const source = this.arrayGroupBy<TrailerComparisonUserComment>(
    this.userComments, 
    comment => comment.trailerComparisonId);
  return from(Object.keys(source)).pipe(
    mergeMap(x => this.trailerComparisonService.updateUserComments(
      x, source[x])
    )
  );
}


this.updateUserCommentsObservable().pipe(
  flatMap(() => from(this.trailerComparisons).pipe(
    mergeMap(trailerComparison => 
      this.trailerComparisonService.saveReviewComplete(
        trailerComparison.trailerComparisonId))
    )
  )
).subscribe(() => {                   
  this.userComments = [];
  this.disableStage1Review = true;
  let snackBarRef = this.snackBar.open('Well done! Stage1 Review Complete has been successfully saved.', 'Dismiss');                   
}, error => {                   
  console.log("Error", error);
  let snackBarRef = this.snackBar.open('Error! ' + error.error.message, 'Dismiss');
});

2 ответа

Вы можете запускать несколько наблюдаемых последовательно, используя concat функция.

concat(
  obs1$,
  obs2$
).subscribe(result => {
  console.log(result);
});

Если каждая наблюдаемая возвращает 1 результат и завершается (HTTP-запрос), то подписчик получит 2 значения - результат obs1$ а затем результат obs2$.

Если вы хотите дождаться, пока оба вернут результат, вы можете использовать toArray функция.

concat(
  obs1$,
  obs2$
).pipe(
  toArray()
).subscribe(result => {
  console.log(result);
});

Результатом подписки теперь будет массив obs1$ результат и obs2$ результат.

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

const trailerComparisons$ = this.trailerComparisons.map(c => 
  this.trailerComparisonService.saveReviewComplete(c.trailerComparisonId)
);

concat(
  this.updateUserCommentsObservable(),
  ...trailerComparisons$
).pipe(
  toArray()
).subscribe(/* subscribe handling */)

ДЕМО: https://stackblitz.com/edit/angular-jldrrh

Чтобы звонить последовательно, вы должны использовать concatMap вместо того mergeMap.

https://rxjs-dev.firebaseapp.com/api/operators/concatMap

Другие вопросы по тегам