Skip to content

Commit 9776334

Browse files
Fix debounce timeout trigger (#293)
* Add tests for a timeout bug * Update test with trigger check * Fix the bug * Unrelated change - better name for internal effect, so it is easier to see in the logs * Better name for throttle timer too * use guard as peer dep requries
1 parent f439c04 commit 9776334

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

src/debounce/debounce.fork.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
createEvent,
88
createStore,
99
sample,
10+
createWatch,
1011
} from 'effector';
1112
import { wait, watch } from '../../test-library';
1213

@@ -203,4 +204,31 @@ describe('edge cases', () => {
203204
expect(listener).toBeCalledTimes(1);
204205
expect(listener).toBeCalledWith('two');
205206
});
207+
208+
test('no trigger call, but timeout change on the fly', async () => {
209+
const trigger = createEvent();
210+
211+
const changeTimeout = createEvent<number>();
212+
const $timeout = createStore(40).on(changeTimeout, (_, x) => x);
213+
const db = debounce({ source: trigger, timeout: $timeout });
214+
215+
const listener = jest.fn();
216+
const triggerListener = jest.fn();
217+
const scope = fork()
218+
createWatch({
219+
unit: db,
220+
fn: listener,
221+
scope,
222+
})
223+
createWatch({
224+
unit: trigger,
225+
fn: triggerListener,
226+
scope,
227+
})
228+
229+
await allSettled(changeTimeout, { scope, params: 10 });
230+
231+
expect(listener).toBeCalledTimes(0);
232+
expect(triggerListener).toBeCalledTimes(0);
233+
})
206234
});

src/debounce/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export function debounce<T>({
8484
});
8585
});
8686
const timerFx = attach({
87+
name: `debounce(${source.shortName || source.kind}) effect`,
8788
source: {
8889
timeoutId: $timeoutId,
8990
rejectPromise: $rejecter,
@@ -126,7 +127,7 @@ export function debounce<T>({
126127
const requestTick = merge([
127128
source,
128129
// debounce timeout is restarted on timeout change
129-
$timeout,
130+
guard({ clock: $timeout, filter: timerFx.pending }),
130131
]);
131132

132133
guard({

src/throttle/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ export function throttle<T>({
3737

3838
const $timeout = toStoreNumber(timeout);
3939

40-
const timerFx = createEffect<number, void>(
41-
(timeout) => new Promise((resolve) => setTimeout(resolve, timeout)),
42-
);
40+
const timerFx = createEffect<number, void>({
41+
name: `throttle(${(source as Event<T>).shortName || source.kind}) effect`,
42+
handler: (timeout) => new Promise((resolve) => setTimeout(resolve, timeout)),
43+
});
4344

4445
// It's ok - nothing will ever start unless source is triggered
4546
const $payload = createStore<T>(null as unknown as T, { serialize: 'ignore' }).on(

0 commit comments

Comments
 (0)