Skip to content

Instantly share code, notes, and snippets.

@nestarz
Last active December 20, 2021 12:59
Show Gist options
  • Save nestarz/383297c5de4a4bf199d2489ff86c5723 to your computer and use it in GitHub Desktop.
Save nestarz/383297c5de4a4bf199d2489ff86c5723 to your computer and use it in GitHub Desktop.
Promise queue with concurrency control
const queue = (id, concurrency = 1) => {
const d = { running: 0, queue: [] };
const c = (globalThis._RQ ?? {})[id] ?? d;
globalThis._RQ = { ...(globalThis._RQ ?? {}), [id]: c };
const inc = (fn) => (c.running++, fn());
return (task) =>
(c.running < concurrency
? Promise.resolve(inc(task))
: new Promise((res) => c.queue.push(() => res(inc(task))))
).finally(
() => (c.running--, c.queue.length > 0 ? c.queue.shift()() : null)
);
};
export const queue = (concurrency = 1) => {
let running = 0;
const queue = [];
const inc = (fn) => (running++, fn());
const run = (res) => (
running--, queue.length > 0 ? queue.shift()() : null, res
);
return (task) =>
(running < concurrency
? Promise.resolve(inc(task))
: new Promise((res) => queue.push(() => res(inc(task))))
).then(run);
};
export const queueFn = (concurrency, fn) => {
const addTask = queue(concurrency);
return (...args) => addTask(() => fn(...args));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment