UNPKG

rxjs

Version:

Reactive Extensions for modern JavaScript

61 lines (55 loc) 2.2 kB
import { Operator } from '../Operator'; import { Subscriber } from '../Subscriber'; import { Observable } from '../Observable'; import { TeardownLogic } from '../Subscription'; import { MonoTypeOperatorFunction } from '../interfaces'; /** * Returns an Observable that mirrors the source Observable with the exception of an `error`. If the source Observable * calls `error`, this method will resubscribe to the source Observable for a maximum of `count` resubscriptions (given * as a number parameter) rather than propagating the `error` call. * * <img src="./img/retry.png" width="100%"> * * Any and all items emitted by the source Observable will be emitted by the resulting Observable, even those emitted * during failed subscriptions. For example, if an Observable fails at first but emits [1, 2] then succeeds the second * time and emits: [1, 2, 3, 4, 5] then the complete stream of emissions and notifications * would be: [1, 2, 1, 2, 3, 4, 5, `complete`]. * @param {number} count - Number of retry attempts before failing. * @return {Observable} The source Observable modified with the retry logic. * @method retry * @owner Observable */ export function retry<T>(count: number = -1): MonoTypeOperatorFunction<T> { return (source: Observable<T>) => source.lift(new RetryOperator(count, source)); } class RetryOperator<T> implements Operator<T, T> { constructor(private count: number, private source: Observable<T>) { } call(subscriber: Subscriber<T>, source: any): TeardownLogic { return source.subscribe(new RetrySubscriber(subscriber, this.count, this.source)); } } /** * We need this JSDoc comment for affecting ESDoc. * @ignore * @extends {Ignored} */ class RetrySubscriber<T> extends Subscriber<T> { constructor(destination: Subscriber<any>, private count: number, private source: Observable<T>) { super(destination); } error(err: any) { if (!this.isStopped) { const { source, count } = this; if (count === 0) { return super.error(err); } else if (count > -1) { this.count = count - 1; } source.subscribe(this._unsubscribeAndRecycle()); } } }