Skip to content

Instantly share code, notes, and snippets.

@alexpsi
Created February 25, 2017 20:31
Show Gist options
  • Select an option

  • Save alexpsi/43dd7fd4d6a263c7485326b843677740 to your computer and use it in GitHub Desktop.

Select an option

Save alexpsi/43dd7fd4d6a263c7485326b843677740 to your computer and use it in GitHub Desktop.
Like Promise.all but executed in chunks, so you can have some async concurrency control.
const chunks = (arr, chunkSize) => {
let results = [];
while (arr.length) results.push(arr.splice(0, chunkSize));
return results;
};
module.exports = (xs, f, concurrency) => {
if (xs.length == 0) return Promise.resolve();
return Promise.all(chunks(xs, concurrency).reduce(
(acc, chunk) => acc.then(() => Promise.all(chunk.map(f))),
Promise.resolve()
));
};
@nk1tz
Copy link

nk1tz commented Sep 17, 2022

Here is my typescript version:

const throttledConcurrencyPromiseAll = async <T>(
  arr: Array<any>,
  f: (v: any) => Promise<T>,
  n = Infinity,
): Promise<T[]> => {
  const results = Array(arr.length);
  const entries = arr.entries();
  const worker = async () => {
    for (const [key, val] of entries) results[key] = await f(val);
  };
  await Promise.all(Array.from({ length: Math.min(arr.length, n) }, worker));
  return results;
};

@StagnantIce
Copy link

Thank you for all comments, i used one of them:

export async function promiseBatch<T>(
    items: Promise<T>[],
    limit: number
): Promise<T[]> {
    let currentChunk = items.slice(0, limit);
    const left = items.slice(limit);
    const result: { value: T; index: number }[] = [];
    let index = 0;
    while (currentChunk.length > 0) {
        await Promise.race(
            currentChunk.map((p, i) => p.then((value) => {
                const newChunk = currentChunk.filter(pi => pi !== p);
                if (newChunk.length !== currentChunk.length) {
                    result.push({ index: i + index, value });
                    const f = left.shift();
                    index++;
                    currentChunk = [...newChunk, ...(f ? [ f ] : [])];
                }
            }))
        );
    }
    return result.sort((a, b) => a.index - b.index).map(v => v.value);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment