diff --git a/desktop/app/src/utils/__tests__/sideEffect.node.tsx b/desktop/app/src/utils/__tests__/sideEffect.node.tsx index 0a5a71146..477a7ead2 100644 --- a/desktop/app/src/utils/__tests__/sideEffect.node.tsx +++ b/desktop/app/src/utils/__tests__/sideEffect.node.tsx @@ -183,42 +183,42 @@ describe('sideeffect', () => { expect(warn.mock.calls[0][0]).toContain("Side effect 'test' took"); }); - // TODO(T64747771): Disabled as it appears to be non-deterministic. - test.skip('throttles correctly', async () => { + test('throttles correctly', async () => { unsubscribe = sideEffect( store, - {name: 'test', throttleMs: 100}, + {name: 'test', throttleMs: 1000}, (s) => s.counter.count, (number) => { events.push(`counter: ${number}`); }, ); + // Fires immediately store.dispatch({type: 'inc'}); - await sleep(10); + await sleep(100); expect(events).toEqual(['counter: 1']); // no new tick in the next 100 ms - await sleep(30); + await sleep(300); store.dispatch({type: 'inc'}); - await sleep(30); + await sleep(300); store.dispatch({type: 'inc'}); expect(events).toEqual(['counter: 1']); - await sleep(100); + await sleep(1000); expect(events).toEqual(['counter: 1', 'counter: 3']); // long time now effect, it will fire right away again - await sleep(200); + await sleep(2000); // ..but firing an event that doesn't match the selector doesn't reset the timer store.dispatch({type: 'unrelated'}); - await sleep(10); + await sleep(100); store.dispatch({type: 'inc'}); store.dispatch({type: 'inc'}); - await sleep(10); + await sleep(100); expect(events).toEqual(['counter: 1', 'counter: 3', 'counter: 5']); }); }); diff --git a/desktop/app/src/utils/sideEffect.tsx b/desktop/app/src/utils/sideEffect.tsx index b760c6eb2..840fd086b 100644 --- a/desktop/app/src/utils/sideEffect.tsx +++ b/desktop/app/src/utils/sideEffect.tsx @@ -33,7 +33,7 @@ export function sideEffect< effect: (selectedState: V, store: Store) => void, ): () => void { let scheduled = false; - let lastRun = 0; + let lastRun = -1; let lastSelectedValue: V = selector(store.getState()); let timeout: NodeJS.Timeout; @@ -78,7 +78,9 @@ export function sideEffect< timeout = setTimeout( run, // Run ASAP (but async) or, if we recently did run, delay until at least 'throttle' time has expired - Math.max(1, lastRun + options.throttleMs - performance.now()), + lastRun === -1 + ? 1 + : Math.max(1, lastRun + options.throttleMs - performance.now()), ); });