Subscriber.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { isFunction } from './util/isFunction';
  2. import { isSubscription, Subscription } from './Subscription';
  3. import { config } from './config';
  4. import { reportUnhandledError } from './util/reportUnhandledError';
  5. import { noop } from './util/noop';
  6. import { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';
  7. import { timeoutProvider } from './scheduler/timeoutProvider';
  8. import { captureError } from './util/errorContext';
  9. export class Subscriber extends Subscription {
  10. constructor(destination) {
  11. super();
  12. this.isStopped = false;
  13. if (destination) {
  14. this.destination = destination;
  15. if (isSubscription(destination)) {
  16. destination.add(this);
  17. }
  18. }
  19. else {
  20. this.destination = EMPTY_OBSERVER;
  21. }
  22. }
  23. static create(next, error, complete) {
  24. return new SafeSubscriber(next, error, complete);
  25. }
  26. next(value) {
  27. if (this.isStopped) {
  28. handleStoppedNotification(nextNotification(value), this);
  29. }
  30. else {
  31. this._next(value);
  32. }
  33. }
  34. error(err) {
  35. if (this.isStopped) {
  36. handleStoppedNotification(errorNotification(err), this);
  37. }
  38. else {
  39. this.isStopped = true;
  40. this._error(err);
  41. }
  42. }
  43. complete() {
  44. if (this.isStopped) {
  45. handleStoppedNotification(COMPLETE_NOTIFICATION, this);
  46. }
  47. else {
  48. this.isStopped = true;
  49. this._complete();
  50. }
  51. }
  52. unsubscribe() {
  53. if (!this.closed) {
  54. this.isStopped = true;
  55. super.unsubscribe();
  56. this.destination = null;
  57. }
  58. }
  59. _next(value) {
  60. this.destination.next(value);
  61. }
  62. _error(err) {
  63. try {
  64. this.destination.error(err);
  65. }
  66. finally {
  67. this.unsubscribe();
  68. }
  69. }
  70. _complete() {
  71. try {
  72. this.destination.complete();
  73. }
  74. finally {
  75. this.unsubscribe();
  76. }
  77. }
  78. }
  79. const _bind = Function.prototype.bind;
  80. function bind(fn, thisArg) {
  81. return _bind.call(fn, thisArg);
  82. }
  83. class ConsumerObserver {
  84. constructor(partialObserver) {
  85. this.partialObserver = partialObserver;
  86. }
  87. next(value) {
  88. const { partialObserver } = this;
  89. if (partialObserver.next) {
  90. try {
  91. partialObserver.next(value);
  92. }
  93. catch (error) {
  94. handleUnhandledError(error);
  95. }
  96. }
  97. }
  98. error(err) {
  99. const { partialObserver } = this;
  100. if (partialObserver.error) {
  101. try {
  102. partialObserver.error(err);
  103. }
  104. catch (error) {
  105. handleUnhandledError(error);
  106. }
  107. }
  108. else {
  109. handleUnhandledError(err);
  110. }
  111. }
  112. complete() {
  113. const { partialObserver } = this;
  114. if (partialObserver.complete) {
  115. try {
  116. partialObserver.complete();
  117. }
  118. catch (error) {
  119. handleUnhandledError(error);
  120. }
  121. }
  122. }
  123. }
  124. export class SafeSubscriber extends Subscriber {
  125. constructor(observerOrNext, error, complete) {
  126. super();
  127. let partialObserver;
  128. if (isFunction(observerOrNext) || !observerOrNext) {
  129. partialObserver = {
  130. next: (observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined),
  131. error: error !== null && error !== void 0 ? error : undefined,
  132. complete: complete !== null && complete !== void 0 ? complete : undefined,
  133. };
  134. }
  135. else {
  136. let context;
  137. if (this && config.useDeprecatedNextContext) {
  138. context = Object.create(observerOrNext);
  139. context.unsubscribe = () => this.unsubscribe();
  140. partialObserver = {
  141. next: observerOrNext.next && bind(observerOrNext.next, context),
  142. error: observerOrNext.error && bind(observerOrNext.error, context),
  143. complete: observerOrNext.complete && bind(observerOrNext.complete, context),
  144. };
  145. }
  146. else {
  147. partialObserver = observerOrNext;
  148. }
  149. }
  150. this.destination = new ConsumerObserver(partialObserver);
  151. }
  152. }
  153. function handleUnhandledError(error) {
  154. if (config.useDeprecatedSynchronousErrorHandling) {
  155. captureError(error);
  156. }
  157. else {
  158. reportUnhandledError(error);
  159. }
  160. }
  161. function defaultErrorHandler(err) {
  162. throw err;
  163. }
  164. function handleStoppedNotification(notification, subscriber) {
  165. const { onStoppedNotification } = config;
  166. onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));
  167. }
  168. export const EMPTY_OBSERVER = {
  169. closed: true,
  170. next: noop,
  171. error: defaultErrorHandler,
  172. complete: noop,
  173. };
  174. //# sourceMappingURL=Subscriber.js.map