Skip to content

Commit a62cff0

Browse files
committed
feat: Add debounceSync.
1 parent f33aa11 commit a62cff0

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

source/operators/debounceSync-spec.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @license Use of this source code is governed by an MIT-style license that
3+
* can be found in the LICENSE file at https://github.com/cartant/rxjs-etc
4+
*/
5+
/*tslint:disable:no-unused-expression rxjs-no-ignored-subscription*/
6+
7+
import { marbles } from "rxjs-marbles";
8+
import { debounceSync } from "./debounceSync";
9+
10+
describe("debounceSync", () => {
11+
it(
12+
"should debounce synchronous values",
13+
marbles((m) => {
14+
const source = m.cold(" (ab)-(cd)---(ef)----|");
15+
const sourceSubs = " ^-------------------!";
16+
const expected = m.cold(" b----d------f-------|");
17+
18+
const destination = source.pipe(debounceSync());
19+
m.expect(destination).toBeObservable(expected);
20+
m.expect(source).toHaveSubscriptions(sourceSubs);
21+
})
22+
);
23+
24+
it(
25+
"should debounce values with synchronous completion",
26+
marbles((m) => {
27+
const source = m.cold(" (ab)-(cd)---(ef|)");
28+
const sourceSubs = " ^-----------!";
29+
const expected = m.cold(" b----d------(f|)");
30+
31+
const destination = source.pipe(debounceSync());
32+
m.expect(destination).toBeObservable(expected);
33+
m.expect(source).toHaveSubscriptions(sourceSubs);
34+
})
35+
);
36+
37+
it(
38+
"should debounce synchronous streams",
39+
marbles((m) => {
40+
const source = m.cold(" (abcdef|)");
41+
const sourceSubs = " (^!)";
42+
const expected = m.cold(" (f|)");
43+
44+
const destination = source.pipe(debounceSync());
45+
m.expect(destination).toBeObservable(expected);
46+
m.expect(source).toHaveSubscriptions(sourceSubs);
47+
})
48+
);
49+
});

source/operators/debounceSync.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @license Use of this source code is governed by an MIT-style license that
3+
* can be found in the LICENSE file at https://github.com/cartant/rxjs-etc
4+
*/
5+
6+
import {
7+
asapScheduler,
8+
MonoTypeOperatorFunction,
9+
Observable,
10+
Subscription,
11+
} from "rxjs";
12+
13+
export function debounceSync<T>(): MonoTypeOperatorFunction<T> {
14+
return (source) =>
15+
new Observable<T>((observer) => {
16+
let actionSubscription: Subscription | undefined;
17+
let actionValue: T | undefined;
18+
const rootSubscription = new Subscription();
19+
rootSubscription.add(
20+
source.subscribe({
21+
complete: () => {
22+
if (actionSubscription) {
23+
observer.next(actionValue);
24+
}
25+
observer.complete();
26+
},
27+
error: (error) => observer.error(error),
28+
next: (value) => {
29+
actionValue = value;
30+
if (!actionSubscription) {
31+
actionSubscription = asapScheduler.schedule(() => {
32+
observer.next(actionValue);
33+
actionSubscription = undefined;
34+
});
35+
rootSubscription.add(actionSubscription);
36+
}
37+
},
38+
})
39+
);
40+
return rootSubscription;
41+
});
42+
}

source/operators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export * from "./bufferRecent";
99
export * from "./concatIfEmpty";
1010
export * from "./concatTap";
1111
export * from "./debounceAfter";
12+
export * from "./debounceSync";
1213
export * from "./debounceTimeSubsequent";
1314
export * from "./defaultObservableIfEmpty";
1415
export * from "./deferFinalize";

0 commit comments

Comments
 (0)