Skip to content

Instantly share code, notes, and snippets.

@crazy4groovy
Last active July 12, 2022 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crazy4groovy/1cf038ec435bac220437c8bbdeeafdb6 to your computer and use it in GitHub Desktop.
Save crazy4groovy/1cf038ec435bac220437c8bbdeeafdb6 to your computer and use it in GitHub Desktop.
A simple locking mechanism (for execution throttling, etc) (JavaScript)
function newThrottler({ isBusy, lock, unlock, waitMs }) {
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
return async function throttler(cb, ...args) {
await Promise.resolve();
while (!!(await isBusy())) {
await delay(await waitMs()); // waits in event loop queue, until it interrupts for another attempt!
}
await lock();
// ... DO ALL WORK for result
const result = await cb.call(this, ...args);
await unlock();
return result;
}
}
const throttler = newThrottler((function(){
let semaphore = 0;
return {
isBusy: async () => (semaphore >= 1),
lock: async () => (semaphore += 1),
unlock: async () => (semaphore -= 1),
waitMs: async () => 1000 + (1000 * Math.random())
};
})());
// eg. usage #1: asyn threads, each result handled separately
function calcResult(num) { ... }
function handleResult(result) { ... }
const final = await Promise.all([1,2,3,4,5,.....].map(num => {
throttler(calcResult, num).then(handleResult);
}));
// eg. usage #2: join threads, all results handled together
function calcResult(num) { ... }
function handleResults(results) { ... }
const results = await Promise.all(
[1,2,3,4,5,.....].map(num => throttler(calcResult, num))
);
const final = handleResults(results);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment