Skip to content

Instantly share code, notes, and snippets.

@AlexAegis
Last active August 4, 2023 08:09
Show Gist options
  • Save AlexAegis/9504c6435eaa6aa4038bf880cdd82551 to your computer and use it in GitHub Desktop.
Save AlexAegis/9504c6435eaa6aa4038bf880cdd82551 to your computer and use it in GitHub Desktop.
buffered-all-settled.ts
const task = (i: number): Promise<number> =>
new Promise((res, rej) => {
setTimeout(
() => {
if (i % 12 === 0) {
console.log('task reject', i);
rej('nope');
} else {
console.log('task resolve', i);
res(i);
}
},
500 + Math.random() * 100,
);
});
export const bufferedAllSettled = async <T, E extends Error>(
tasks: (() => Promise<T>)[],
bufferSize = 25,
): Promise<PromiseSettledResult<T>[]> => {
const buffer: Map<() => Promise<T>, Promise<T | E>> = new Map();
const results: PromiseSettledResult<T>[] = [];
while (tasks.length) {
while (buffer.size < bufferSize) {
const task = tasks.shift()!;
const promise = task()
.then((value) => {
results.push({ status: 'fulfilled', value });
buffer.delete(task);
return value;
})
.catch((error: E) => {
results.push({ status: 'rejected', reason: error });
buffer.delete(task);
return error;
});
buffer.set(task, promise);
}
await Promise.any(buffer.values());
}
await Promise.allSettled(buffer.values());
return results;
};
(async () => {
const tasks = Array.from({ length: 100 }).map((_, i) => () => task(i));
const results = await bufferedAllSettled(tasks);
console.log('final results', results);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment