Last active
June 27, 2019 14:35
-
-
Save ur001/be61f88fd31aad06ce2d6e6a8f5e7483 to your computer and use it in GitHub Desktop.
Promise based Lock and Queue
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
/** | |
* Асинхронная очередь с локами на чтение/запись | |
*/ | |
class Queue { | |
constructor() { | |
this.queue = []; | |
this.readLock = new Lock(); | |
this.writeLock = new Lock(); | |
this.setEmpty(); | |
} | |
setEmpty() { | |
this.notEmpty = new Promise(resolve => this.setNotEmpty = resolve); | |
} | |
async put(task) { | |
let unlock = await this.writeLock.acquire(); | |
this.queue.push(task); | |
this.setNotEmpty(); | |
unlock(); | |
} | |
async get() { | |
let unlock = await this.readLock.acquire(); | |
await this.notEmpty; | |
let task = this.queue.shift(); | |
this.queue.length || this.setEmpty(); | |
unlock(); | |
return task; | |
} | |
} | |
class Lock { | |
constructor() { | |
this.promise = Promise.resolve(); | |
} | |
acquire() { | |
let unlockNext; | |
let willLock = new Promise(resolve => unlockNext = resolve); | |
let unlock = this.promise.then(() => unlockNext); | |
this.promise = this.promise.then(() => willLock); | |
return unlock; | |
} | |
} | |
/***************** TEST *********************/ | |
queue = new Queue(); | |
(async () => console.log('POP1', await queue.get()))(); | |
(async () => console.log('POP2', await queue.get()))(); | |
queue.put(1); | |
// Output: | |
// POP 1 | |
listenQueue = async(queue) => { | |
let task; | |
while(task = await queue.get()) { | |
console.log('TASK', task); | |
} | |
}; | |
listenQueue(queue); | |
queue.put(2); | |
queue.put(3); | |
// Output: | |
// POP 2 | |
// TASK 3 | |
(async () => console.log('POP3', await queue.get()))(); | |
(async () => console.log('POP4', await queue.get()))(); | |
queue.put('hello1'); | |
queue.put('hello2'); | |
queue.put('hello3'); | |
queue.put('hello4'); | |
// Output: | |
// TASK hello1 | |
// POP3 hello2 | |
// POP4 hello3 | |
// TASK hello4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment