Skip to content

Commit

Permalink
Move throttle and debounce from metasync
Browse files Browse the repository at this point in the history
  • Loading branch information
tshemsedinov committed Dec 17, 2024
1 parent 6e3ffd8 commit 51f292c
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 2 deletions.
40 changes: 39 additions & 1 deletion lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,42 @@ const timeoutify = (promise, msec) =>
);
});

module.exports = { toBool, timeout, delay, timeoutify };
const throttle = (timeout, fn, ...args) => {
let timer;
let wait = false;

const execute = args
? (...pars) => (pars ? fn(...args, ...pars) : fn(...args))
: (...pars) => (pars ? fn(...pars) : fn());

const delayed = (...pars) => {
timer = undefined;
if (wait) execute(...pars);
};

const throttled = (...pars) => {
if (!timer) {
timer = setTimeout(delayed, timeout, ...pars);
wait = false;
execute(...pars);
}
wait = true;
};

return throttled;
};

const debounce = (timeout, fn, ...args) => {
let timer;

const debounced = () => (args ? fn(...args) : fn());

const wrapped = () => {
if (timer) clearTimeout(timer);
timer = setTimeout(debounced, timeout);
};

return wrapped;
};

module.exports = { toBool, timeout, delay, timeoutify, throttle, debounce };
102 changes: 101 additions & 1 deletion test/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@

const test = require('node:test');
const assert = require('node:assert');
const { toBool, timeout, delay, timeoutify } = require('..');
const {
toBool,
timeout,
delay,
timeoutify,
throttle,
debounce,
} = require('..');

test('Async: toBool', async () => {
const success = await Promise.resolve('success').then(...toBool);
Expand Down Expand Up @@ -67,3 +74,96 @@ test('Async: timeoutify', async () => {
assert.ifError(new Error('Should not be executed'));
}
});

test('Async: throttle', () => {
let callCount = 0;

const fn = (arg1, arg2, ...otherArgs) => {
assert.strictEqual(arg1, 'someVal');
assert.strictEqual(arg2, 4);
assert.strictEqual(otherArgs, []);
callCount++;
};

const throttledFn = throttle(1, fn, 'someVal', 4);

throttledFn();
assert.strictEqual(callCount, 1);
throttledFn();
throttledFn();
assert.strictEqual(callCount, 1);
});

test('Async: throttle merge args', () => {
let callCount = 0;

const fn = (arg1, arg2, ...otherArgs) => {
assert.strictEqual(arg1, 'someVal');
assert.strictEqual(arg2, 4);
assert.strictEqual(otherArgs, ['str']);
callCount++;
};

const throttledFn = throttle(1, fn, 'someVal', 4);

throttledFn('str');
assert.strictEqual(callCount, 1);
throttledFn('str');
throttledFn('str');
assert.strictEqual(callCount, 1);
});

test('Async: throttle without arguments', () => {
let callCount = 0;

const fn = (...args) => {
assert.strictEqual(args, []);
callCount++;
};

const throttledFn = throttle(1, fn);

throttledFn();
assert.strictEqual(callCount, 1);
throttledFn();
throttledFn();
assert.strictEqual(callCount, 1);
});

test('Async: debounce', async () => {
const { promise, resolve } = Promise.withResolvers();
let count = 0;

const fn = (arg1, arg2, ...otherArgs) => {
assert.strictEqual(arg1, 'someVal');
assert.strictEqual(arg2, 4);
assert.strictEqual(otherArgs, []);
count++;
resolve();
};

const debouncedFn = debounce(1, fn, 'someVal', 4);

debouncedFn();
debouncedFn();
assert.strictEqual(count, 0);
return promise;
});

test('Async: debounce without arguments', async () => {
const { promise, resolve } = Promise.withResolvers();
let count = 0;

const fn = (...args) => {
assert.strictEqual(args, []);
count++;
resolve();
};

const debouncedFn = debounce(1, fn);

debouncedFn();
debouncedFn();
assert.strictEqual(count, 0);
return promise;
});

0 comments on commit 51f292c

Please sign in to comment.