retryWhen.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { Subject } from '../Subject';
  2. import { tryCatch } from '../util/tryCatch';
  3. import { errorObject } from '../util/errorObject';
  4. import { OuterSubscriber } from '../OuterSubscriber';
  5. import { subscribeToResult } from '../util/subscribeToResult';
  6. /**
  7. * Returns an Observable that mirrors the source Observable with the exception of an `error`. If the source Observable
  8. * calls `error`, this method will emit the Throwable that caused the error to the Observable returned from `notifier`.
  9. * If that Observable calls `complete` or `error` then this method will call `complete` or `error` on the child
  10. * subscription. Otherwise this method will resubscribe to the source Observable.
  11. *
  12. * <img src="./img/retryWhen.png" width="100%">
  13. *
  14. * @param {function(errors: Observable): Observable} notifier - Receives an Observable of notifications with which a
  15. * user can `complete` or `error`, aborting the retry.
  16. * @return {Observable} The source Observable modified with retry logic.
  17. * @method retryWhen
  18. * @owner Observable
  19. */
  20. export function retryWhen(notifier) {
  21. return (source) => source.lift(new RetryWhenOperator(notifier, source));
  22. }
  23. class RetryWhenOperator {
  24. constructor(notifier, source) {
  25. this.notifier = notifier;
  26. this.source = source;
  27. }
  28. call(subscriber, source) {
  29. return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source));
  30. }
  31. }
  32. /**
  33. * We need this JSDoc comment for affecting ESDoc.
  34. * @ignore
  35. * @extends {Ignored}
  36. */
  37. class RetryWhenSubscriber extends OuterSubscriber {
  38. constructor(destination, notifier, source) {
  39. super(destination);
  40. this.notifier = notifier;
  41. this.source = source;
  42. }
  43. error(err) {
  44. if (!this.isStopped) {
  45. let errors = this.errors;
  46. let retries = this.retries;
  47. let retriesSubscription = this.retriesSubscription;
  48. if (!retries) {
  49. errors = new Subject();
  50. retries = tryCatch(this.notifier)(errors);
  51. if (retries === errorObject) {
  52. return super.error(errorObject.e);
  53. }
  54. retriesSubscription = subscribeToResult(this, retries);
  55. }
  56. else {
  57. this.errors = null;
  58. this.retriesSubscription = null;
  59. }
  60. this._unsubscribeAndRecycle();
  61. this.errors = errors;
  62. this.retries = retries;
  63. this.retriesSubscription = retriesSubscription;
  64. errors.next(err);
  65. }
  66. }
  67. /** @deprecated internal use only */ _unsubscribe() {
  68. const { errors, retriesSubscription } = this;
  69. if (errors) {
  70. errors.unsubscribe();
  71. this.errors = null;
  72. }
  73. if (retriesSubscription) {
  74. retriesSubscription.unsubscribe();
  75. this.retriesSubscription = null;
  76. }
  77. this.retries = null;
  78. }
  79. notifyNext(outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  80. const { errors, retries, retriesSubscription } = this;
  81. this.errors = null;
  82. this.retries = null;
  83. this.retriesSubscription = null;
  84. this._unsubscribeAndRecycle();
  85. this.errors = errors;
  86. this.retries = retries;
  87. this.retriesSubscription = retriesSubscription;
  88. this.source.subscribe(this);
  89. }
  90. }
  91. //# sourceMappingURL=retryWhen.js.map