Skip to content

Commit

Permalink
fix(debounce): don't signal on complete
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the observable returned by the debounce operator's
duration selector must emit a next notification to end the duration.
Complete notifications no longer end the duration.
  • Loading branch information
cartant authored and benlesh committed Nov 3, 2020
1 parent 4af0227 commit c919c68
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 32 deletions.
58 changes: 29 additions & 29 deletions spec/operators/debounce-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('debounce', () => {
it('should debounce values by a specified cold Observable', () => {
testScheduler.run(({ cold, hot, expectObservable }) => {
const e1 = hot(' -a--bc--d---|');
const e2 = cold(' --| ');
const e2 = cold(' --x ');
const expected = '---a---c--d-|';

const result = e1.pipe(debounce(() => e2));
Expand Down Expand Up @@ -364,11 +364,11 @@ describe('debounce', () => {
});
});

it('should mirror the source when given an empty selector Observable', () => {
it('should ignore all values except last, when given an empty selector Observable', () => {
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' --------a-x-yz---bxy---z--c--x--y--z|');
const e1subs = ' ^-----------------------------------!';
const expected = '--------a-x-yz---bxy---z--c--x--y--z|';
const e1 = hot(' --------a-x-yz---bxy---z--c--x--y--z| ');
const e1subs = ' ^-----------------------------------! ';
const expected = '------------------------------------(z|)';

function selectorFunction(x: string) {
return EMPTY;
Expand All @@ -394,20 +394,20 @@ describe('debounce', () => {
});
});

it('should delay element by selector observable completes when it does not emits', () => {
it('should not delay by selector observable completes when it does not emits', () => {
testScheduler.run(({ cold, hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' --------a--------b--------c---------|');
const e1subs = ' ^-----------------------------------!';
const expected = '---------a---------b---------c------|';
const e1 = hot(' --------a--------b--------c---------| ');
const e1subs = ' ^-----------------------------------! ';
const expected = '------------------------------------(c|)';
const selector = [
cold(' -| '),
cold(' --| '),
cold(' ---| '),
cold(' -| '),
cold(' --| '),
cold(' ---| '),
];
const selectorSubs = [
' --------^! ',
' -----------------^-! ',
' --------------------------^--! ',
' --------^! ',
' -----------------^-! ',
' --------------------------^--! ',
];

expectObservable(e1.pipe(debounce(() => selector.shift()!))).toBe(expected);
Expand All @@ -418,24 +418,24 @@ describe('debounce', () => {
});
});

it('should debounce by selector observable completes when it does not emits', () => {
it('should not debounce by selector observable completes when it does not emits', () => {
testScheduler.run(({ cold, hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' ----a--b-c---------de-------------|');
const e1subs = ' ^---------------------------------!';
const expected = '-----a------c------------e--------|';
const e1 = hot(' ----a--b-c---------de-------------| ');
const e1subs = ' ^---------------------------------! ';
const expected = '----------------------------------(e|)';
const selector = [
cold(' -| '),
cold(' --| '),
cold(' ---| '),
cold(' ----| '),
cold(' -----| '),
cold(' -| '),
cold(' --| '),
cold(' ---| '),
cold(' ----| '),
cold(' -----| '),
];
const selectorSubs = [
' ----^! ',
' -------^-! ',
' ---------^--! ',
' -------------------^! ',
' --------------------^----! ',
' ----^! ',
' -------^-! ',
' ---------^--! ',
' -------------------^! ',
' --------------------^----! ',
];

expectObservable(e1.pipe(debounce(() => selector.shift()!))).toBe(expected);
Expand Down
6 changes: 3 additions & 3 deletions src/internal/operators/debounce.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @prettier */
import { Subscriber } from '../Subscriber';
import { MonoTypeOperatorFunction, ObservableInput } from '../types';

import { operate } from '../util/lift';
import { noop } from '../util/noop';
import { OperatorSubscriber } from './OperatorSubscriber';
import { innerFrom } from '../observable/from';

Expand All @@ -20,7 +20,7 @@ import { innerFrom } from '../observable/from';
* This operator keeps track of the most recent notification from the source
* Observable, and spawns a duration Observable by calling the
* `durationSelector` function. The notification is emitted only when the duration
* Observable emits a notification or completes, and if no other notification was emitted on
* Observable emits a next notification, and if no other notification was emitted on
* the source Observable since the duration Observable was spawned. If a new
* notification appears before the duration Observable emits, the previous notification will
* not be emitted and a new duration is scheduled from `durationSelector` is scheduled.
Expand Down Expand Up @@ -97,7 +97,7 @@ export function debounce<T>(durationSelector: (value: T) => ObservableInput<any>
lastValue = value;
// Capture our duration subscriber, so we can unsubscribe it when we're notified
// and we're going to emit the value.
durationSubscriber = new OperatorSubscriber(subscriber, emit, undefined, emit);
durationSubscriber = new OperatorSubscriber(subscriber, emit, undefined, noop);
// Subscribe to the duration.
innerFrom(durationSelector(value)).subscribe(durationSubscriber);
},
Expand Down

0 comments on commit c919c68

Please sign in to comment.