Skip to content

Instantly share code, notes, and snippets.

@krisselden
Created April 27, 2021 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krisselden/a7a5e2b0429a4cbbbab396c185f0604f to your computer and use it in GitHub Desktop.
Save krisselden/a7a5e2b0429a4cbbbab396c185f0604f to your computer and use it in GitHub Desktop.
const log = (() => {
const start = Date.now();
return (msg, ...args) => {
const elasped = Date.now() - start;
console.log(`%os ${msg}`, elasped / 1000, ...args);
};
})();
async function doAsyncTask(name) {
log("started %o", name);
await new Promise((resolve) => setTimeout(resolve, 1000));
log("ended %o", name);
return name;
}
function* taskStream(total) {
let i = 0;
while (i < total) {
yield doAsyncTask(`task ${++i}`);
}
}
async function* forEachConcurrent(stream, limit) {
let seq = 0;
let running = new Map();
const pushNext = (promise) => {
const id = ++seq;
running.set(
id,
promise.then((result) => [id, result])
);
};
const nextDone = async () => {
const [id, result] = await Promise.race(running.values());
running.delete(id);
return result;
};
for (const promise of stream) {
pushNext(promise);
if (running.size === limit) {
yield await nextDone();
}
}
while (running.size > 0) {
yield await nextDone();
}
}
(async () => {
const stream = taskStream(10);
for await (const result of forEachConcurrent(stream, 3)) {
log("result %o", result);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment