diff --git a/spec/Observable-spec.ts b/spec/Observable-spec.ts index 7790aa9c8d..beac26c286 100644 --- a/spec/Observable-spec.ts +++ b/spec/Observable-spec.ts @@ -599,6 +599,45 @@ describe('Observable', () => { console.log = _log; }); }); + + it('should fully propogate disposal when subscribed with a Subscriber', () => { + let observableUnsubscribed = false; + let subscriberUnsubscribed = false; + let subscriptionUnsubscribed = false; + + const subscriber = new Subscriber(); + // verify unsubscribe is called on the Subscriber + subscriber.add(() => subscriberUnsubscribed = true); + const source = new Observable(_ => () => observableUnsubscribed = true); + const subscription = source.subscribe(subscriber); + // verify unsubscribe is called on children of the returned Subscription + subscription.add(() => subscriptionUnsubscribed = true); + + subscription.unsubscribe(); + + expect(observableUnsubscribed).to.be.true; + expect(subscriberUnsubscribed).to.be.true; + expect(subscriptionUnsubscribed).to.be.true; + }); + + it('should fully propogate disposal when subscribed with a Subscriber-like', () => { + let observableUnsubscribed = false; + let subscriberUnsubscribed = false; + let subscriptionUnsubscribed = false; + + // verify unsubscribe is called on the "Subscriber" (quack-quack) + const subscriber = { unsubscribe: () => subscriberUnsubscribed = true }; + const source = new Observable(_ => () => observableUnsubscribed = true); + const subscription = source.subscribe( subscriber as Subscriber); + // verify unsubscribe is called on children of the returned Subscription + subscription.add(() => subscriptionUnsubscribed = true); + + subscription.unsubscribe(); + + expect(observableUnsubscribed).to.be.true; + expect(subscriberUnsubscribed).to.be.true; + expect(subscriptionUnsubscribed).to.be.true; + }); }); describe('pipe', () => { diff --git a/src/internal/Subscriber.ts b/src/internal/Subscriber.ts index d6d76ea464..b1ef72a232 100644 --- a/src/internal/Subscriber.ts +++ b/src/internal/Subscriber.ts @@ -77,6 +77,7 @@ export class Subscriber extends Subscription implements Observer { } else { this.syncErrorThrowable = true; this.destination = new SafeSubscriber(this, > destinationOrNext); + this.add(> this.destination); } break; } diff --git a/src/internal/util/toSubscriber.ts b/src/internal/util/toSubscriber.ts index ba7ad27fcb..1e9eeaa3d2 100644 --- a/src/internal/util/toSubscriber.ts +++ b/src/internal/util/toSubscriber.ts @@ -18,8 +18,11 @@ export function toSubscriber( } } - if (!nextOrObserver && !error && !complete) { - return new Subscriber(emptyObserver); + if (!error && !complete) { + if (!nextOrObserver) { + return new Subscriber(emptyObserver); + } + return new Subscriber(nextOrObserver); } return new Subscriber(nextOrObserver, error, complete);