Files
ssh-updater/node_modules/sb-promise-queue/lib/esm/index.mjs
T
dinlo e0a986eb30 Initial commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:45:31 +08:00

71 lines
1.9 KiB
JavaScript

class PromiseQueue {
constructor({ concurrency = 1 } = {}) {
this.options = { concurrency };
this.running = 0;
this.queue = [];
this.idleCallbacks = [];
}
clear() {
this.queue = [];
}
onIdle(callback) {
this.idleCallbacks.push(callback);
return () => {
const index = this.idleCallbacks.indexOf(callback);
if (index !== -1) {
this.idleCallbacks.splice(index, 1);
}
};
}
waitTillIdle() {
return new Promise((resolve) => {
if (this.running === 0) {
resolve();
return;
}
const dispose = this.onIdle(() => {
dispose();
resolve();
});
});
}
add(callback) {
return new Promise((resolve, reject) => {
const runCallback = () => {
this.running += 1;
try {
Promise.resolve(callback()).then((val) => {
resolve(val);
this.processNext();
}, (err) => {
reject(err);
this.processNext();
});
}
catch (err) {
reject(err);
this.processNext();
}
};
if (this.running >= this.options.concurrency) {
this.queue.push(runCallback);
}
else {
runCallback();
}
});
}
// Internal function, don't use
processNext() {
this.running -= 1;
const callback = this.queue.shift();
if (callback) {
callback();
}
else if (this.running === 0) {
this.idleCallbacks.forEach((item) => item());
}
}
}
export { PromiseQueue };