📅  最后修改于: 2022-03-11 15:02:24.140000             🧑  作者: Mango
function Semaphore(max) {
var counter = 0;
var waiting = [];
var take = function() {
if (waiting.length > 0 && counter < max){
counter++;
let promise = waiting.shift();
promise.resolve();
}
}
this.acquire = function() {
if(counter < max) {
counter++
return new Promise(resolve => {
resolve();
});
} else {
return new Promise((resolve, err) => {
waiting.push({resolve: resolve, err: err});
});
}
}
this.release = function() {
counter--;
take();
}
this.purge = function() {
let unresolved = waiting.length;
for (let i = 0; i < unresolved; i++) {
waiting[i].err('Task has been purged.');
}
counter = 0;
waiting = [];
return unresolved;
}
}
// testing the semaphore
let sema = new Semaphore(2);
async function test(id) {
console.log('queueing task', id);
try {
await sema.acquire();
console.log('running task', id);
setTimeout(() => {
sema.release();
}, 2000);
} catch (e) {
console.error(id, e);
}
}
test(1);
test(2);
test(3);
test(4);
test(5);
setTimeout(() => {
test(10);
test(11);
test(12);
}, 1500);
setTimeout(() => {
test(20);
test(21);
test(22);
}, 2700);
// PURGE TEST
// setTimeout(() => {sema.purge();}, 2200);