// create a new lock
const locker = new Locker()
// wait for lock
const releaseLock = await locker.waitForLock()
// we have the lock! do stuff
// release the lock
releaseLock()
Last active
April 25, 2018 12:27
-
-
Save jpwilliams/98bd667e03eeaab37b704f8e7d14bf5d to your computer and use it in GitHub Desktop.
A promise-based locking mechanism.
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
export class Locker { | |
constructor () { | |
this._locked = false | |
this._waiting = [] | |
} | |
waitForLock (opts = {}) { | |
if (!this._locked) { | |
this._locked = true | |
return Promise.resolve(this._getReleaser()) | |
} | |
const { timeout = 0 } = opts | |
return new Promise((resolve, reject) => { | |
const releaser = () => resolve(this._getReleaser()) | |
this._waiting.push(releaser) | |
if (timeout) { | |
setTimeout(() => { | |
this._clearFn(releaser) | |
reject(new Error('Timed out')) | |
}, timeout) | |
} | |
}) | |
} | |
_getReleaser () { | |
let released = false | |
return () => { | |
if (released) return | |
released = true | |
const next = this._waiting.shift() | |
if (next) { | |
next() | |
return | |
} | |
this._locked = false | |
} | |
} | |
_clearFn (fn) { | |
const idx = this._waiting.indexOf(fn) | |
if (idx > -1) this._waiting.splice(idx, 1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment