Last active
May 26, 2020 15:52
-
-
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.
This file contains hidden or 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
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()') | |
} |
This file contains hidden or 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
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