Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

onErrorResumeNext.ts 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { Observable } from '../Observable';
  2. import { from } from '../observable/from';
  3. import { Operator } from '../Operator';
  4. import { Subscriber } from '../Subscriber';
  5. import { Subscription } from '../Subscription';
  6. import { isArray } from '../util/isArray';
  7. import { ObservableInput, OperatorFunction } from '../types';
  8. import { SimpleOuterSubscriber, SimpleInnerSubscriber, innerSubscribe } from '../innerSubscribe';
  9. /* tslint:disable:max-line-length */
  10. export function onErrorResumeNext<T>(): OperatorFunction<T, T>;
  11. export function onErrorResumeNext<T, T2>(v: ObservableInput<T2>): OperatorFunction<T, T | T2>;
  12. export function onErrorResumeNext<T, T2, T3>(v: ObservableInput<T2>, v2: ObservableInput<T3>): OperatorFunction<T, T | T2 | T3>;
  13. export function onErrorResumeNext<T, T2, T3, T4>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>): OperatorFunction<T, T | T2 | T3 | T4>;
  14. export function onErrorResumeNext<T, T2, T3, T4, T5>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>): OperatorFunction<T, T | T2 | T3 | T4 | T5>;
  15. export function onErrorResumeNext<T, T2, T3, T4, T5, T6>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>, v5: ObservableInput<T6>): OperatorFunction<T, T | T2 | T3 | T4 | T5 | T6>;
  16. export function onErrorResumeNext<T, T2, T3, T4, T5, T6, T7>(v: ObservableInput<T2>, v2: ObservableInput<T3>, v3: ObservableInput<T4>, v4: ObservableInput<T5>, v5: ObservableInput<T6>, v6: ObservableInput<T7>): OperatorFunction<T, T | T2 | T3 | T4 | T5 | T6 | T7>;
  17. export function onErrorResumeNext<T, R>(...observables: Array<ObservableInput<any>>): OperatorFunction<T, T | R>;
  18. export function onErrorResumeNext<T, R>(array: ObservableInput<any>[]): OperatorFunction<T, T | R>;
  19. /* tslint:enable:max-line-length */
  20. /**
  21. * When any of the provided Observable emits an complete or error notification, it immediately subscribes to the next one
  22. * that was passed.
  23. *
  24. * <span class="informal">Execute series of Observables no matter what, even if it means swallowing errors.</span>
  25. *
  26. * ![](onErrorResumeNext.png)
  27. *
  28. * `onErrorResumeNext` is an operator that accepts a series of Observables, provided either directly as
  29. * arguments or as an array. If no single Observable is provided, returned Observable will simply behave the same
  30. * as the source.
  31. *
  32. * `onErrorResumeNext` returns an Observable that starts by subscribing and re-emitting values from the source Observable.
  33. * When its stream of values ends - no matter if Observable completed or emitted an error - `onErrorResumeNext`
  34. * will subscribe to the first Observable that was passed as an argument to the method. It will start re-emitting
  35. * its values as well and - again - when that stream ends, `onErrorResumeNext` will proceed to subscribing yet another
  36. * Observable in provided series, no matter if previous Observable completed or ended with an error. This will
  37. * be happening until there is no more Observables left in the series, at which point returned Observable will
  38. * complete - even if the last subscribed stream ended with an error.
  39. *
  40. * `onErrorResumeNext` can be therefore thought of as version of {@link concat} operator, which is more permissive
  41. * when it comes to the errors emitted by its input Observables. While `concat` subscribes to the next Observable
  42. * in series only if previous one successfully completed, `onErrorResumeNext` subscribes even if it ended with
  43. * an error.
  44. *
  45. * Note that you do not get any access to errors emitted by the Observables. In particular do not
  46. * expect these errors to appear in error callback passed to {@link Observable#subscribe}. If you want to take
  47. * specific actions based on what error was emitted by an Observable, you should try out {@link catchError} instead.
  48. *
  49. *
  50. * ## Example
  51. * Subscribe to the next Observable after map fails
  52. * ```ts
  53. * import { of } from 'rxjs';
  54. * import { onErrorResumeNext, map } from 'rxjs/operators';
  55. *
  56. * of(1, 2, 3, 0).pipe(
  57. * map(x => {
  58. * if (x === 0) { throw Error(); }
  59. * return 10 / x;
  60. * }),
  61. * onErrorResumeNext(of(1, 2, 3)),
  62. * )
  63. * .subscribe(
  64. * val => console.log(val),
  65. * err => console.log(err), // Will never be called.
  66. * () => console.log('that\'s it!')
  67. * );
  68. *
  69. * // Logs:
  70. * // 10
  71. * // 5
  72. * // 3.3333333333333335
  73. * // 1
  74. * // 2
  75. * // 3
  76. * // "that's it!"
  77. * ```
  78. *
  79. * @see {@link concat}
  80. * @see {@link catchError}
  81. *
  82. * @param {...ObservableInput} observables Observables passed either directly or as an array.
  83. * @return {Observable} An Observable that emits values from source Observable, but - if it errors - subscribes
  84. * to the next passed Observable and so on, until it completes or runs out of Observables.
  85. * @method onErrorResumeNext
  86. * @owner Observable
  87. */
  88. export function onErrorResumeNext<T, R>(...nextSources: Array<ObservableInput<any> |
  89. Array<ObservableInput<any>>>): OperatorFunction<T, R> {
  90. if (nextSources.length === 1 && isArray(nextSources[0])) {
  91. nextSources = <Array<Observable<any>>>nextSources[0];
  92. }
  93. return (source: Observable<T>) => source.lift(new OnErrorResumeNextOperator<T, R>(nextSources));
  94. }
  95. /* tslint:disable:max-line-length */
  96. export function onErrorResumeNextStatic<R>(v: ObservableInput<R>): Observable<R>;
  97. export function onErrorResumeNextStatic<T2, T3, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>): Observable<R>;
  98. export function onErrorResumeNextStatic<T2, T3, T4, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>): Observable<R>;
  99. export function onErrorResumeNextStatic<T2, T3, T4, T5, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>): Observable<R>;
  100. export function onErrorResumeNextStatic<T2, T3, T4, T5, T6, R>(v2: ObservableInput<T2>, v3: ObservableInput<T3>, v4: ObservableInput<T4>, v5: ObservableInput<T5>, v6: ObservableInput<T6>): Observable<R>;
  101. export function onErrorResumeNextStatic<R>(...observables: Array<ObservableInput<any> | ((...values: Array<any>) => R)>): Observable<R>;
  102. export function onErrorResumeNextStatic<R>(array: ObservableInput<any>[]): Observable<R>;
  103. /* tslint:enable:max-line-length */
  104. export function onErrorResumeNextStatic<T, R>(...nextSources: Array<ObservableInput<any> |
  105. Array<ObservableInput<any>> |
  106. ((...values: Array<any>) => R)>): Observable<R> {
  107. let source: ObservableInput<any>|undefined = undefined;
  108. if (nextSources.length === 1 && isArray(nextSources[0])) {
  109. nextSources = nextSources[0] as ObservableInput<any>[];
  110. }
  111. // TODO: resolve issue with passing no arguments.
  112. source = nextSources.shift()!;
  113. return from(source).lift(new OnErrorResumeNextOperator<T, R>(nextSources));
  114. }
  115. class OnErrorResumeNextOperator<T, R> implements Operator<T, R> {
  116. constructor(private nextSources: Array<ObservableInput<any>>) {
  117. }
  118. call(subscriber: Subscriber<R>, source: any): any {
  119. return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources));
  120. }
  121. }
  122. class OnErrorResumeNextSubscriber<T, R> extends SimpleOuterSubscriber<T, R> {
  123. constructor(protected destination: Subscriber<T>,
  124. private nextSources: Array<ObservableInput<any>>) {
  125. super(destination);
  126. }
  127. notifyError(): void {
  128. this.subscribeToNextSource();
  129. }
  130. notifyComplete(): void {
  131. this.subscribeToNextSource();
  132. }
  133. protected _error(err: any): void {
  134. this.subscribeToNextSource();
  135. this.unsubscribe();
  136. }
  137. protected _complete(): void {
  138. this.subscribeToNextSource();
  139. this.unsubscribe();
  140. }
  141. private subscribeToNextSource(): void {
  142. const next = this.nextSources.shift();
  143. if (!!next) {
  144. const innerSubscriber = new SimpleInnerSubscriber(this);
  145. const destination = this.destination as Subscription;
  146. destination.add(innerSubscriber);
  147. const innerSubscription = innerSubscribe(next, innerSubscriber);
  148. // The returned subscription will usually be the subscriber that was
  149. // passed. However, interop subscribers will be wrapped and for
  150. // unsubscriptions to chain correctly, the wrapper needs to be added, too.
  151. if (innerSubscription !== innerSubscriber) {
  152. destination.add(innerSubscription);
  153. }
  154. } else {
  155. this.destination.complete();
  156. }
  157. }
  158. }