await-semaphore
Version:
Awaitable semaphore/mutex
63 lines (56 loc) • 1.51 kB
text/typescript
export class Semaphore {
private tasks: (() => void)[] = [];
count: number;
constructor(count: number) {
this.count = count;
}
private sched() {
if (this.count > 0 && this.tasks.length > 0) {
this.count--;
let next = this.tasks.shift();
if (next === undefined) {
throw "Unexpected undefined value in tasks list";
}
next();
}
}
public acquire() {
return new Promise<() => void>((res, rej) => {
var task = () => {
var released = false;
res(() => {
if (!released) {
released = true;
this.count++;
this.sched();
}
});
};
this.tasks.push(task);
if (process && process.nextTick) {
process.nextTick(this.sched.bind(this));
} else {
setImmediate(this.sched.bind(this));
}
});
}
public use<T>(f: () => Promise<T>) {
return this.acquire()
.then(release => {
return f()
.then((res) => {
release();
return res;
})
.catch((err) => {
release();
throw err;
});
});
}
}
export class Mutex extends Semaphore {
constructor() {
super(1);
}
}