1 import { isFunction } from './util/isFunction';
2 import { empty as emptyObserver } from './Observer';
3 import { Subscription } from './Subscription';
4 import { rxSubscriber as rxSubscriberSymbol } from '../internal/symbol/rxSubscriber';
5 import { config } from './config';
6 import { hostReportError } from './util/hostReportError';
7 export class Subscriber extends Subscription {
8 constructor(destinationOrNext, error, complete) {
10 this.syncErrorValue = null;
11 this.syncErrorThrown = false;
12 this.syncErrorThrowable = false;
13 this.isStopped = false;
14 switch (arguments.length) {
16 this.destination = emptyObserver;
19 if (!destinationOrNext) {
20 this.destination = emptyObserver;
23 if (typeof destinationOrNext === 'object') {
24 if (destinationOrNext instanceof Subscriber) {
25 this.syncErrorThrowable = destinationOrNext.syncErrorThrowable;
26 this.destination = destinationOrNext;
27 destinationOrNext.add(this);
30 this.syncErrorThrowable = true;
31 this.destination = new SafeSubscriber(this, destinationOrNext);
36 this.syncErrorThrowable = true;
37 this.destination = new SafeSubscriber(this, destinationOrNext, error, complete);
41 [rxSubscriberSymbol]() { return this; }
42 static create(next, error, complete) {
43 const subscriber = new Subscriber(next, error, complete);
44 subscriber.syncErrorThrowable = false;
48 if (!this.isStopped) {
53 if (!this.isStopped) {
54 this.isStopped = true;
59 if (!this.isStopped) {
60 this.isStopped = true;
68 this.isStopped = true;
72 this.destination.next(value);
75 this.destination.error(err);
79 this.destination.complete();
82 _unsubscribeAndRecycle() {
83 const { _parentOrParents } = this;
84 this._parentOrParents = null;
87 this.isStopped = false;
88 this._parentOrParents = _parentOrParents;
92 export class SafeSubscriber extends Subscriber {
93 constructor(_parentSubscriber, observerOrNext, error, complete) {
95 this._parentSubscriber = _parentSubscriber;
98 if (isFunction(observerOrNext)) {
99 next = observerOrNext;
101 else if (observerOrNext) {
102 next = observerOrNext.next;
103 error = observerOrNext.error;
104 complete = observerOrNext.complete;
105 if (observerOrNext !== emptyObserver) {
106 context = Object.create(observerOrNext);
107 if (isFunction(context.unsubscribe)) {
108 this.add(context.unsubscribe.bind(context));
110 context.unsubscribe = this.unsubscribe.bind(this);
113 this._context = context;
116 this._complete = complete;
119 if (!this.isStopped && this._next) {
120 const { _parentSubscriber } = this;
121 if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
122 this.__tryOrUnsub(this._next, value);
124 else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) {
130 if (!this.isStopped) {
131 const { _parentSubscriber } = this;
132 const { useDeprecatedSynchronousErrorHandling } = config;
134 if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
135 this.__tryOrUnsub(this._error, err);
139 this.__tryOrSetError(_parentSubscriber, this._error, err);
143 else if (!_parentSubscriber.syncErrorThrowable) {
145 if (useDeprecatedSynchronousErrorHandling) {
148 hostReportError(err);
151 if (useDeprecatedSynchronousErrorHandling) {
152 _parentSubscriber.syncErrorValue = err;
153 _parentSubscriber.syncErrorThrown = true;
156 hostReportError(err);
163 if (!this.isStopped) {
164 const { _parentSubscriber } = this;
165 if (this._complete) {
166 const wrappedComplete = () => this._complete.call(this._context);
167 if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {
168 this.__tryOrUnsub(wrappedComplete);
172 this.__tryOrSetError(_parentSubscriber, wrappedComplete);
181 __tryOrUnsub(fn, value) {
183 fn.call(this._context, value);
187 if (config.useDeprecatedSynchronousErrorHandling) {
191 hostReportError(err);
195 __tryOrSetError(parent, fn, value) {
196 if (!config.useDeprecatedSynchronousErrorHandling) {
197 throw new Error('bad call');
200 fn.call(this._context, value);
203 if (config.useDeprecatedSynchronousErrorHandling) {
204 parent.syncErrorValue = err;
205 parent.syncErrorThrown = true;
209 hostReportError(err);
216 const { _parentSubscriber } = this;
217 this._context = null;
218 this._parentSubscriber = null;
219 _parentSubscriber.unsubscribe();
222 //# sourceMappingURL=Subscriber.js.map