Skip to content

Instantly share code, notes, and snippets.

@ur001
Last active June 27, 2019 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ur001/be61f88fd31aad06ce2d6e6a8f5e7483 to your computer and use it in GitHub Desktop.
Save ur001/be61f88fd31aad06ce2d6e6a8f5e7483 to your computer and use it in GitHub Desktop.
Promise based Lock and Queue
/**
* Асинхронная очередь с локами на чтение/запись
*/
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