diff --git a/spec/Subscriber-spec.ts b/spec/Subscriber-spec.ts index ee92d32a01..f4d63bccce 100644 --- a/spec/Subscriber-spec.ts +++ b/spec/Subscriber-spec.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { SafeSubscriber } from 'rxjs/internal/Subscriber'; -import { Subscriber, Observable, config, of } from 'rxjs'; +import { Subscriber, Observable, config, of, Observer } from 'rxjs'; import { asInteropSubscriber } from './helpers/interop-helper'; import { getRegisteredTeardowns } from './helpers/subscription'; @@ -242,4 +242,30 @@ describe('Subscriber', () => { expect(consumer.valuesProcessed).not.to.equal(['new', 'new']); }); }); + + const FinalizationRegistry = (global as any).FinalizationRegistry; + if (FinalizationRegistry) { + + it('should not leak the destination', (done) => { + let observer: Observer | undefined = { + next() { /* noop */ }, + error() { /* noop */ }, + complete() { /* noop */ } + }; + + const registry = new FinalizationRegistry((value: any) => { + expect(value).to.equal('observer'); + done(); + }); + registry.register(observer, 'observer'); + + const subscription = of(42).subscribe(observer); + + observer = undefined; + global.gc(); + }); + + } else { + console.warn(`No support for FinalizationRegistry in Node ${process.version}`); + } }); \ No newline at end of file diff --git a/spec/operators/shareReplay-spec.ts b/spec/operators/shareReplay-spec.ts index bedbdafeb1..d70bee5fa8 100644 --- a/spec/operators/shareReplay-spec.ts +++ b/spec/operators/shareReplay-spec.ts @@ -323,11 +323,12 @@ describe('shareReplay operator', () => { if (FinalizationRegistry) { it('should not leak the subscriber for sync sources', (done) => { + let callback: (() => void) | undefined = () => { /* noop */ }; + const registry = new FinalizationRegistry((value: any) => { expect(value).to.equal('callback'); done(); }); - let callback: (() => void) | undefined = () => { /* noop */ }; registry.register(callback, 'callback'); const shared = of(42).pipe(shareReplay(1)); diff --git a/src/internal/Subscriber.ts b/src/internal/Subscriber.ts index 9779d78225..29b1942eb6 100644 --- a/src/internal/Subscriber.ts +++ b/src/internal/Subscriber.ts @@ -105,6 +105,7 @@ export class Subscriber extends Subscription implements Observer { if (!this.closed) { this.isStopped = true; super.unsubscribe(); + this.destination = null!; } } diff --git a/src/internal/operators/OperatorSubscriber.ts b/src/internal/operators/OperatorSubscriber.ts index a9c32866ac..740eaeb6fb 100644 --- a/src/internal/operators/OperatorSubscriber.ts +++ b/src/internal/operators/OperatorSubscriber.ts @@ -42,7 +42,7 @@ export class OperatorSubscriber extends Subscriber { try { onNext(value); } catch (err) { - this.destination.error(err); + destination.error(err); } } : super._next; @@ -52,7 +52,7 @@ export class OperatorSubscriber extends Subscriber { onError(err); } catch (err) { // Send any errors that occur down stream. - this.destination.error(err); + destination.error(err); } finally { // Ensure teardown. this.unsubscribe(); @@ -65,7 +65,7 @@ export class OperatorSubscriber extends Subscriber { onComplete(); } catch (err) { // Send any errors that occur down stream. - this.destination.error(err); + destination.error(err); } finally { // Ensure teardown. this.unsubscribe();