首页 手册 参考 源码 测试 关于中文版Repository
暗色主题亮色主题

es6/operator/retryWhen.js

  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. * 返回一个 Observable, 该 Observable 是源 Observable 不包含错误异常的镜像。 如果源头 Observable 触发
  8. * `error`, 这个方法会发出引起错误的 Throwable 给 `notifier` 返回的 Observable。 如果该 Observable 触发 `complete` 或者 `error`
  9. * 则该方法会使子订阅触发 `complete` 和 `error`。 否则该方法会重新订阅源 Observable。
  10. *
  11. * <img src="./img/retryWhen.png" width="100%">
  12. *
  13. * @param {function(errors: Observable): Observable} notifier - 接受一个用户可以`complete` 或者 `error`的通知型 Observable, 终止重试。
  14. * @return {Observable} 使用重试逻辑修改过的源 Observable。
  15. * @method retryWhen
  16. * @owner Observable
  17. */
  18. export function retryWhen(notifier) {
  19. return this.lift(new RetryWhenOperator(notifier, this));
  20. }
  21. class RetryWhenOperator {
  22. constructor(notifier, source) {
  23. this.notifier = notifier;
  24. this.source = source;
  25. }
  26. call(subscriber, source) {
  27. return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source));
  28. }
  29. }
  30. /**
  31. * We need this JSDoc comment for affecting ESDoc.
  32. * @ignore
  33. * @extends {Ignored}
  34. */
  35. class RetryWhenSubscriber extends OuterSubscriber {
  36. constructor(destination, notifier, source) {
  37. super(destination);
  38. this.notifier = notifier;
  39. this.source = source;
  40. }
  41. error(err) {
  42. if (!this.isStopped) {
  43. let errors = this.errors;
  44. let retries = this.retries;
  45. let retriesSubscription = this.retriesSubscription;
  46. if (!retries) {
  47. errors = new Subject();
  48. retries = tryCatch(this.notifier)(errors);
  49. if (retries === errorObject) {
  50. return super.error(errorObject.e);
  51. }
  52. retriesSubscription = subscribeToResult(this, retries);
  53. }
  54. else {
  55. this.errors = null;
  56. this.retriesSubscription = null;
  57. }
  58. this._unsubscribeAndRecycle();
  59. this.errors = errors;
  60. this.retries = retries;
  61. this.retriesSubscription = retriesSubscription;
  62. errors.next(err);
  63. }
  64. }
  65. _unsubscribe() {
  66. const { errors, retriesSubscription } = this;
  67. if (errors) {
  68. errors.unsubscribe();
  69. this.errors = null;
  70. }
  71. if (retriesSubscription) {
  72. retriesSubscription.unsubscribe();
  73. this.retriesSubscription = null;
  74. }
  75. this.retries = null;
  76. }
  77. notifyNext(outerValue, innerValue, outerIndex, innerIndex, innerSub) {
  78. const { errors, retries, retriesSubscription } = this;
  79. this.errors = null;
  80. this.retries = null;
  81. this.retriesSubscription = null;
  82. this._unsubscribeAndRecycle();
  83. this.errors = errors;
  84. this.retries = retries;
  85. this.retriesSubscription = retriesSubscription;
  86. this.source.subscribe(this);
  87. }
  88. }
  89. //# sourceMappingURL=retryWhen.js.map