Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active December 15, 2019 05:10
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 intrnl/d30dcb819ac5642827707ee80d9a304f to your computer and use it in GitHub Desktop.
Save intrnl/d30dcb819ac5642827707ee80d9a304f to your computer and use it in GitHub Desktop.
Functional locking mechanism
class LockError extends Error {}
function createLock () {
/** @type {boolean} */
let locked = false;
/** @type {PromiseObject[]} */
let pending = [];
function acquire () {
return new Promise((resolve, reject) => {
const promise = { resolve, reject };
if (locked) {
pending.push(promise);
} else {
locked = true;
promise.resolve();
}
});
}
function release () {
if (pending.length) {
const nextPromise = pending.shift();
nextPromise.resolve();
} else {
locked = false;
}
}
function clear () {
const clearance = [...pending];
pending.length = 0;
for (let promise of clearance) {
promise.reject(new LockError('Lock queue was cleared'));
}
}
return {
get locked () { return locked; },
get count () { return pending.length; },
acquire,
release,
clear,
};
}
/**
* @typedef {object} PromiseObject
* @property {Function} resolve
* @property {Function} reject
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment