Skip to content

Instantly share code, notes, and snippets.

@mattlockyer
Last active May 26, 2020 15:52
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 mattlockyer/a4044f2ce42930e6bf8e3450ca619a92 to your computer and use it in GitHub Desktop.
Save mattlockyer/a4044f2ce42930e6bf8e3450ca619a92 to your computer and use it in GitHub Desktop.
Javascript Mutex to prevent re-entry from multiple method calls. Protect methods that modify app, localStorage or IndexedDB.
import { lock, unlock } from './mutex.js'
async function processCallsLikeQueue() {
// stop method calls here
await lock('processCallsLikeQueue()')
// ...
// code to protect from re-entry
// i.e. prevent multiple simultaneous calls to this part of the code
// ...
// let next method call in
unlock('processCallsLikeQueue()')
}
let promises = {}, resolvers = {}
// uid should be unique per code you protect, e.g. the method signature
export const lock = async (uid = 'default') => {
if (promises[uid]) { // check if lock exists
await promises[uid] // wait on lock promise
await lock() // stack lock check after promise resolves
return // prev methods do nothing
}
// there is no lock, so we'll "acquire" it here
promises[uid] = new Promise((resolve) => resolvers[uid] = () => {
promises[uid] = null // release
resolve() // resolve
})
}
export const unlock = (uid = 'default') => {
if (resolvers[uid]) {
resolvers[uid]()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment