Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dfcarpenter/43b537c81e7c334a1ac26f3bf4760751 to your computer and use it in GitHub Desktop.
Save dfcarpenter/43b537c81e7c334a1ac26f3bf4760751 to your computer and use it in GitHub Desktop.
// Mutex implementation originally taken from https://github.com/mgtitimoli/await-mutex
/* Why do you need mutexes in a single threaded context ?
* Presumably instances of `MyObject` can be accessed by functions which are running while this function is suspended,
* waiting for the network call. It's single threaded, as in only one thing happens at a time from JS's point of view,
* but other functions can be invoked (by a request coming in, or a UI event etc) while an asynchronous operation
* is awaiting completion.
*/
class Mutex {
constructor() {
this._locking = Promise.resolve();
this._locked = false;
}
isLocked() {
return this._locked;
}
lock() {
this._locked = true;
let unlockNext;
let willLock = new Promise(resolve => unlockNext = resolve);
willLock.then(() => this._locked = false);
let willUnlock = this._locking.then(() => unlockNext);
this._locking = this._locking.then(() => willLock);
return willUnlock;
}
}
export default Mutex;
//use elsewhere
import Mutex from 'lib/mutex';
class MyObject {
constructor() {
this.m = new Mutex();
}
async someNetworkCall() {
let unlock = await this.m.lock();
doSomethingAsynchronous().then((result) => {
// handle result
unlock();
}).catch((err) => {
// handle error
unlock();
});
}
}
let mo = new MyObject();
mo.someNetworkCall();
// The next call will wait until the first call is finished
mo.someNetworkCall();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment