Skip to content

Commit f28955f

Browse files
PSanetrabenlesh
authored andcommitted
fix(Observable): Fix Observable.subscribe to add operator TeardownLogic to returned Subscription. (#4434)
1 parent 9b4f358 commit f28955f

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

spec/Observable-spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { Observer, TeardownLogic } from '../src/internal/types';
55
import { cold, expectObservable, expectSubscriptions } from './helpers/marble-testing';
66
import { map } from '../src/internal/operators/map';
77
import { noop } from '../src/internal/util/noop';
8+
import { NEVER } from '../src/internal/observable/never';
9+
import { Subscriber } from '../src/internal/Subscriber';
10+
import { Operator } from '../src/internal/Operator';
811

912
declare const asDiagram: any, rxTestScheduler: any;
1013
const Observable = Rx.Observable;
@@ -697,6 +700,24 @@ describe('Observable.lift', () => {
697700
}
698701
}
699702

703+
it('should return Observable which calls TeardownLogic of operator on unsubscription', (done) => {
704+
705+
const myOperator: Operator<any, any> = {
706+
call: (subscriber: Subscriber<any>, source: any) => {
707+
const subscription = source.subscribe((x: any) => subscriber.next(x));
708+
return () => {
709+
subscription.unsubscribe();
710+
done();
711+
};
712+
}
713+
};
714+
715+
NEVER.lift(myOperator)
716+
.subscribe()
717+
.unsubscribe();
718+
719+
});
720+
700721
it('should be overrideable in a custom Observable type that composes', (done) => {
701722
const result = new MyCustomObservable<number>((observer) => {
702723
observer.next(1);

src/internal/Observable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export class Observable<T> implements Subscribable<T> {
204204
const sink = toSubscriber(observerOrNext, error, complete);
205205

206206
if (operator) {
207-
operator.call(sink, this.source);
207+
sink.add(operator.call(sink, this.source));
208208
} else {
209209
sink.add(
210210
this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ?

src/internal/Subscription.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,15 @@ export class Subscription implements SubscriptionLike {
164164
}
165165
}
166166

167-
// Optimize for the common case when adding the first subscription.
168-
const subscriptions = this._subscriptions;
169-
if (subscriptions) {
170-
subscriptions.push(subscription);
171-
} else {
172-
this._subscriptions = [subscription];
167+
if (subscription._addParent(this)) {
168+
// Optimize for the common case when adding the first subscription.
169+
const subscriptions = this._subscriptions;
170+
if (subscriptions) {
171+
subscriptions.push(subscription);
172+
} else {
173+
this._subscriptions = [subscription];
174+
}
173175
}
174-
subscription._addParent(this);
175176

176177
return subscription;
177178
}
@@ -193,20 +194,26 @@ export class Subscription implements SubscriptionLike {
193194
}
194195

195196
/** @internal */
196-
private _addParent(parent: Subscription) {
197+
private _addParent(parent: Subscription): boolean {
197198
let { _parent, _parents } = this;
198-
if (!_parent || _parent === parent) {
199-
// If we don't have a parent, or the new parent is the same as the
200-
// current parent, then set this._parent to the new parent.
199+
if (_parent === parent) {
200+
// If the new parent is the same as the current parent, then do nothing.
201+
return false;
202+
} else if (!_parent) {
203+
// If we don't have a parent, then set this._parent to the new parent.
201204
this._parent = parent;
205+
return true;
202206
} else if (!_parents) {
203207
// If there's already one parent, but not multiple, allocate an Array to
204208
// store the rest of the parent Subscriptions.
205209
this._parents = [parent];
210+
return true;
206211
} else if (_parents.indexOf(parent) === -1) {
207212
// Only add the new parent to the _parents list if it's not already there.
208213
_parents.push(parent);
214+
return true;
209215
}
216+
return false;
210217
}
211218
}
212219

0 commit comments

Comments
 (0)