Можно использовать рекурсивную l oop с условием остановки, согласно которому количество попыток превышает максимально допустимое количество попыток. Затем вы можете объединить одну наблюдаемую часть вашего действия «Повторить» с наблюдаемым патчем. Если вы отредактируете фрагмент, чтобы изменить maxAttempts
на число ниже 5, вы увидите, что выполняется действие «сбой».
В качестве отступления - вам может потребоваться перепроверить использование switchMap
при запуске вызова API, который вносит постоянные изменения. Вот статья , в которой подробно объясняется проблема.
const {of, operators, throwError, timer, concat} = rxjs;
const {switchMap, catchError, flatMap} = operators;
const maxAttempts = 60;
const patch = (article, attempt) => {
if (attempt < 5)
return throwError(new Error('server unavailable'));
return of(article);
};
const action$ = of('patch.id');
const saveArticle1 =
action$.pipe(
switchMap((article) => {
const loop = (attempt) => {
return patch(article, attempt).pipe(
flatMap((response) => of({
type: 'saved',
value: response,
})),
catchError(error => {
if (attempt > maxAttempts) return of({ type: 'failed' });
return timer(1000).pipe(
switchMap(() =>
concat(
of({ type: 'retrying' }),
loop(attempt + 1)
)
)
);
})
);
};
return loop(0);
}),
);
saveArticle1.subscribe({
next: x => console.log('next', x),
error: e => console.error(e),
complete: () => console.log('complete')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.js"></script>