Last active
July 12, 2022 04:13
-
-
Save crazy4groovy/1cf038ec435bac220437c8bbdeeafdb6 to your computer and use it in GitHub Desktop.
A simple locking mechanism (for execution throttling, etc) (JavaScript)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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