diff --git a/spec/operators/debounceTime-spec.ts b/spec/operators/debounceTime-spec.ts index 0774928d03..b347db1888 100644 --- a/spec/operators/debounceTime-spec.ts +++ b/spec/operators/debounceTime-spec.ts @@ -1,10 +1,12 @@ /** @prettier */ import { expect } from 'chai'; -import { of, Subject } from 'rxjs'; -import { debounceTime, mergeMap } from 'rxjs/operators'; +import { NEVER, of, Subject } from 'rxjs'; +import { AnimationFrameAction } from 'rxjs/internal/scheduler/AnimationFrameAction'; +import { AnimationFrameScheduler } from 'rxjs/internal/scheduler/AnimationFrameScheduler'; +import { debounceTime, mergeMap, startWith } from 'rxjs/operators'; import { TestScheduler } from 'rxjs/testing'; -import { observableMatcher } from '../helpers/observableMatcher'; import { VirtualTimeScheduler } from '../../src/internal/scheduler/VirtualTimeScheduler'; +import { observableMatcher } from '../helpers/observableMatcher'; /** @test {debounceTime} */ describe('debounceTime', () => { @@ -221,4 +223,21 @@ describe('debounceTime', () => { expect(results).to.deep.equal([1, 2]); }); + + it('should unsubscribe from the scheduled debounce action when downstream unsubscribes', () => { + const scheduler = new AnimationFrameScheduler(AnimationFrameAction); + + expect(scheduler._scheduled).to.not.exist; + expect(scheduler.actions).to.be.empty; + + const subscription = NEVER.pipe(startWith(1), debounceTime(0, scheduler)).subscribe(); + + expect(scheduler._scheduled).to.exist; + expect(scheduler.actions.length).to.equal(1); + + subscription.unsubscribe(); + + expect(scheduler._scheduled).to.not.exist; + expect(scheduler.actions).to.be.empty; + }); }); diff --git a/src/internal/operators/debounceTime.ts b/src/internal/operators/debounceTime.ts index 78cd632c63..875116fe88 100644 --- a/src/internal/operators/debounceTime.ts +++ b/src/internal/operators/debounceTime.ts @@ -86,6 +86,7 @@ export function debounceTime(dueTime: number, scheduler: SchedulerLike = asyn if (now < targetTime) { // On that case, re-schedule to the new target activeTask = this.schedule(undefined, targetTime - now); + subscriber.add(activeTask); return; } @@ -102,6 +103,7 @@ export function debounceTime(dueTime: number, scheduler: SchedulerLike = asyn // Only set up a task if it's not already up if (!activeTask) { activeTask = scheduler.schedule(emitWhenIdle, dueTime); + subscriber.add(activeTask); } }, () => {