Подпишитесь на несколько обращений в службу последовательно
Мне нужно сделать 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 */)
Чтобы звонить последовательно, вы должны использовать concatMap
вместо того mergeMap
.