Created
June 3, 2016 17:29
-
-
Save dfcarpenter/43b537c81e7c334a1ac26f3bf4760751 to your computer and use it in GitHub Desktop.
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
// 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