
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
async-throttle-cache
Advanced tools
Throttle or debounce asynchronous functions and return cached result for each function calls. It can be used for rate limit.
Throttle or debounce asynchronous functions and return cached result for each function calls. It can be used for rate limit.
npm install async-throttle-cache --save
import asyncThrottleCache from 'async-throttle-cache';
Direct <script> include
<script src="https://cdn.jsdelivr.net/npm/async-throttle-cache"></script>
const throttleFn = asyncThrottleCache(fn[, wait = 0[, options = {
key: (...args) => JSON.stringify(args),
serialize: result => Promise.resolve(result),
deserialize: result => Promise.resolve(result),
debounce: undefined | true | false | { leading: true },
}]]);
Creates a throttled function that only invokes fn at most once per every wait milliseconds, and returns cached result.
You can specify how to generate cache key. Different cache key will re-invoke fn to get a new result.
serialize and deserialize is for cached result, they could be asynchronous functions.
debounce is for debounce mode, if true, fn will be invoked after wait time since last call.
For example, clone result for each time throttled function execution in 1000 milliseconds. It's useful when you tend to modify the result object.
const throttleFn = asyncThrottleCache(fn, 1000, {
serialize: async result => JSON.stringify(result),
deserialize: async result => JSON.parse(result),
});
// define a asynchronous function, return after 100ms
function fn(arg1, arg2) {
return new Promise((resolve) => {
setTimeout(() => resolve({
arg1,
arg2
}), 100);
});
}
const throttleFn150ms = asyncThrottleCache(fn, 150); // longer then function execution
(async () => {
throttleFn150ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 100ms
throttleFn150ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
await throttleFn150ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 100ms
await throttleFn150ms(2, 2); // from cache, return { arg1: 2, arg2: 2 } at 100ms
})();
const throttleFn50ms = asyncThrottleCache(fn, 50); // shorter then function execution
(async () => {
throttleFn50ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 100ms
throttleFn50ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
await throttleFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 100ms
await throttleFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 200ms
})();
const throttleFn150ms = asyncThrottleCache(fn, 150, {
key: (arg1, arg2) => JSON.stringify(arg2), // uses arg2 as key
});
(async () => {
throttleFn150ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 100ms
throttleFn150ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
await throttleFn150ms(2, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
await throttleFn150ms(2, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
})();
const debounceFn250ms = asyncThrottleCache(fn, 250, {
debounce: true,
});
(async () => {
debounceFn250ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 350ms
debounceFn250ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 350ms
debounceFn250ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 750ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn250ms(2, 2); // from cache, return { arg1: 2, arg2: 2 } at 750ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn250ms(2, 2); // from cache, return { arg1: 2, arg2: 2 } at 750ms
})();
const debounceFn50ms = asyncThrottleCache(fn, 50, {
debounce: true,
});
(async () => {
debounceFn50ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 150ms
debounceFn50ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 150ms
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 150ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 350ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 550ms
})();
const debounceFn250ms = asyncThrottleCache(fn, 250, {
debounce: {
leading: true,
},
});
(async () => {
debounceFn250ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 100ms
debounceFn250ms(1, 2); // from cache, return { arg1: 1, arg2: 2 } at 100ms
debounceFn250ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 100ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn250ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 750ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn250ms(2, 2); // from cache, return { arg1: 2, arg2: 2 } at 750ms
})();
const debounceFn50ms = asyncThrottleCache(fn, 50, {
debounce: {
leading: true,
},
});
(async () => {
debounceFn50ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 100ms
debounceFn50ms(1, 2); // invoke, return { arg1: 1, arg2: 2 } at 150ms
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 100ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 300ms
await new Promise((resolve) => setTimeout(resolve, 200));
debounceFn50ms(2, 2); // invoke, return { arg1: 2, arg2: 2 } at 500ms
})();
FAQs
Throttle or debounce asynchronous functions and return cached result for each function calls. It can be used for rate limit.
The npm package async-throttle-cache receives a total of 6 weekly downloads. As such, async-throttle-cache popularity was classified as not popular.
We found that async-throttle-cache demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.