Skip to content

Commit

Permalink
update throttle
Browse files Browse the repository at this point in the history
  • Loading branch information
afshinm committed Jan 1, 2024
1 parent e6ab514 commit 905f15c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class Config {
tableRef: createRef(),
width: '100%',
height: 'auto',
processingThrottleMs: 50,
processingThrottleMs: 100,
autoWidth: true,
style: {},
className: {},
Expand Down
41 changes: 23 additions & 18 deletions src/util/throttle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,34 @@
* Throttle a given function
* @param fn Function to be called
* @param wait Throttle timeout in milliseconds
* @param leading whether or not to call "fn" immediately
* @returns Throttled function
*/
export const throttle = (fn: (...args) => void, wait = 100, leading = true) => {
let inThrottle: boolean;
let lastFn: ReturnType<typeof setTimeout>;
let lastTime: number;
export const throttle = (fn: (...args) => void, wait = 100) => {

Check warning on line 7 in src/util/throttle.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
let timeoutId: ReturnType<typeof setTimeout>;
let lastTime = Date.now();

const execute = (...args) => {
lastTime = Date.now();
fn(...args);
};

return (...args) => {
if (!inThrottle) {
if (leading) {
fn(...args);
}
lastTime = Date.now();
inThrottle = true;
const currentTime = Date.now();
const elapsed = currentTime - lastTime;

if (elapsed >= wait) {
// If enough time has passed since the last call, execute the function immediately
execute(args);

Check warning on line 22 in src/util/throttle.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
} else {
clearTimeout(lastFn);
lastFn = setTimeout(() => {
if (Date.now() - lastTime >= wait) {
fn(...args);
lastTime = Date.now();
}
}, Math.max(wait - (Date.now() - lastTime), 0));
// If not enough time has passed, schedule the function call after the remaining delay
if (timeoutId) {
clearTimeout(timeoutId);
}

timeoutId = setTimeout(() => {
execute(args);
timeoutId = null;
}, wait - elapsed);
}

Check warning on line 33 in src/util/throttle.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
};
};
2 changes: 1 addition & 1 deletion src/view/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function Container() {
log.error(e);
dispatch(actions.SetDataErrored());
}
}, config.processingThrottleMs, false);
}, config.processingThrottleMs);

useEffect(() => {
// set the initial header object
Expand Down
69 changes: 69 additions & 0 deletions tests/jest/util/throttle.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { throttle } from '../../../src/util/throttle';

const sleep = (wait: number) => new Promise((r) => setTimeout(r, wait));

describe('throttle', () => {
it('should throttle calls', async () => {
const wait = 100;
const fn = jest.fn();
const throttled = throttle(fn, wait);

throttled('a');
sleep(wait - 5)
throttled('b');
sleep(wait - 10)
throttled('c');

await sleep(wait);

expect(fn).toBeCalledTimes(1);
expect(fn).toBeCalledWith(['c']);
});

it('should execute the first call', async () => {
const wait = 100;
const fn = jest.fn();
const throttled = throttle(fn, wait);

throttled();

await sleep(wait);

expect(fn).toBeCalledTimes(1);
});

it('should call at trailing edge of the timeout', async () => {
const wait = 100;
const fn = jest.fn();
const throttled = throttle(fn, wait);

throttled();

expect(fn).toBeCalledTimes(0);

await sleep(wait);

expect(fn).toBeCalledTimes(1);
});

it('should call after the timer', async () => {
const wait = 100;
const fn = jest.fn();
const throttled = throttle(fn, wait);

throttled();
await sleep(wait);

expect(fn).toBeCalledTimes(1);

throttled();
await sleep(wait);

expect(fn).toBeCalledTimes(2);

throttled();
await sleep(wait);

expect(fn).toBeCalledTimes(3);
});
});

0 comments on commit 905f15c

Please sign in to comment.