Skip to content

Commit

Permalink
feat(esl-utils): aggregate decorator function introduced
Browse files Browse the repository at this point in the history
  • Loading branch information
ala-n committed May 20, 2021
1 parent b28a91f commit 0915fd6
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/modules/esl-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Even if you use the whole utils module, it is still tiny.


- ### Async

- #### [Aggregate](./async/aggregate.ts) - throttle function decorator with aggregation.
Limit decorated function call to one, with aggregated list of call's argument. Decorated function call happens when the timeout is passed from the first call in the group.

- #### [Debounce](./async/debounce.ts) - debounce function decorator.
Debouncing is a pattern commonly used for rate limiting function calls with a timeout.
Expand Down
1 change: 1 addition & 0 deletions src/modules/esl-utils/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export * from './decorators/memoize';
export * from './decorators/prop';

// Function
export * from './async/aggregate';
export * from './async/promise';
export * from './async/raf';
export * from './async/debounce';
Expand Down
19 changes: 19 additions & 0 deletions src/modules/esl-utils/async/aggregate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Aggregate is the function decorator similar to {@link debounce} which is collect calls until the `time` from
* the last call is exceeded and them coll the `callback` with the list of happened original calls arguments.
*/
export function aggregate<T>(callback: (this: void, args: T[]) => void, time: number) {
let calls: T[] = [];
let timeout = 0;

const emit = () => {
callback(calls);
calls = [];
timeout = 0;
};

return function (arg: T) {
calls.push(arg);
timeout = timeout || window.setTimeout(emit, time);
};
}
41 changes: 41 additions & 0 deletions src/modules/esl-utils/async/test/aggregate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {aggregate} from '../aggregate';

describe('async/aggregate', () => {
test('single call', (done) => {
const fn = jest.fn();
const agFn = aggregate(fn, 10);

agFn(1);

setTimeout(() => {
expect(fn).toBeCalledTimes(1);
expect(fn).lastCalledWith([1]);

agFn(2);
setTimeout(() => {
expect(fn).toBeCalledTimes(2);
expect(fn).lastCalledWith([2]);

done();
}, 40);
}, 40);
}, 200);
test('multiple calls', (done) => {
const fn = jest.fn();
const agFn = aggregate(fn, 10);

agFn(1);
agFn(2);

setTimeout(() => agFn(3));
setTimeout(() => agFn(4), 5);

expect(fn).toBeCalledTimes(0);

setTimeout(() => {
expect(fn).toBeCalledTimes(1);
expect(fn).lastCalledWith([1, 2, 3, 4]);
done();
}, 100);
}, 200);
});

0 comments on commit 0915fd6

Please sign in to comment.