Подписаться на несколько вызовов службы последовательно - PullRequest
0 голосов
/ 13 марта 2020

Мне нужно сделать 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 ]

0 голосов
/ 13 марта 2020

Вы можете запустить несколько наблюдаемых последовательно, используя функцию 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 */)

DEMO: https://stackblitz.com/edit/angular-jldrrh

0 голосов
/ 13 марта 2020

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...