[RxJS] Retry with increasing time

import { Observable, throwError, timer } from 'rxjs';
import { mergeMap, finalize } from 'rxjs/operators';

export const genericRetryStrategy = ({
  maxRetryAttempts = 3,
  scalingDuration = 1000,
  excludedStatusCodes = [],
}: {
  maxRetryAttempts?: number;
  scalingDuration?: number;
  excludedStatusCodes?: number[];
} = {}) => (attempts: Observable<any>) => {
  return attempts.pipe(
    mergeMap((error, i) => {
      const retryAttempt = i + 1;
      // if maximum number of retries have been met
      // or response is a status code we don't wish to retry, throw error
      if (retryAttempt > maxRetryAttempts || excludedStatusCodes.find((e) => e === error.status)) {
        return throwError(error);
      }
      console.log(`Attempt ${retryAttempt}: retrying in ${retryAttempt * scalingDuration}ms`);
      // retry after 1s, 2s, etc...
      return timer(retryAttempt * scalingDuration);
    }),
    finalize(() => console.log('We are done!'))
  );
};

USAGE:

    const careTeams$: Observable<any[]> = getMockData([]).pipe(
      map((results) => {
        if (result.length == 0) {
          throw results;
        }
        return results;
      }),
      retryWhen(
        genericRetryStrategy({
          maxRetryAttempts: 10,
          scalingDuration: 100,
          excludedStatusCodes: [500],
        })
      ),
      catchError((err) => of([]))
    );

 

posted @ 2021-08-12 15:45  Zhentiw  阅读(70)  评论(0编辑  收藏  举报