enum MutexLockStatus { LOCKED , UNLOCKED } type Callback = ( ... args : any [ ] ) => any ; export class export default class Mutex { static param { string } key returns { Promise < void > } memberof public static async lock ( key ) { return new Promise < void > ( ( resolve ) => { if ( this . keys [ key ] === undefined || this . keys [ key ] === MutexLockStatus . UNLOCKED ) { this . keys [ key ] = MutexLockStatus . LOCKED ; resolve ( ) ; } else { this . onUnlockEvent ( key , ( ) => { this . keys [ key ] = MutexLockStatus . LOCKED ; resolve ( ) ; } ) ; } } ) ; } static param { string } key returns { Promise < void > } memberof public static async unlock ( key ) { return new Promise < void > ( ( resolve ) => { if ( this . keys [ key ] === MutexLockStatus . LOCKED ) { this . emitUnlockEvent ( key ) ; } delete this . keys [ key ] ; resolve ( ) ; } ) ; } private static keys : { [ key ] : MutexLockStatus ; } = { } ; private static listeners : { [ key ] : Callback [ ] ; } = { } ; private static onUnlockEvent ( key , handler ) { if ( this . listeners [ key ] === undefined ) { this . listeners [ key ] = [ handler ] ; } else { this . listeners [ key ] . push ( handler ) ; } } private static emitUnlockEvent ( key ) { if ( this . listeners [ key ] !== undefined && this . listeners [ key ] . length > 0 ) { const handler = this . listeners [ key ] . shift ( ) ; setImmediate ( ( ) => { handler ! . call ( this ) ; } ) ; } } }