Skip to content

Instantly share code, notes, and snippets.

@ValeriiVasin
Last active January 21, 2019 18:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ValeriiVasin/9e61328544be6f7bbfc90b6db7092dd4 to your computer and use it in GitHub Desktop.
Save ValeriiVasin/9e61328544be6f7bbfc90b6db7092dd4 to your computer and use it in GitHub Desktop.
parallel async iteration via generator
(async function() {
async function f1() {
return new Promise(res => {
setTimeout(() => {
res('1.1');
}, 1000);
});
}
async function f2() {
return new Promise(res => {
setTimeout(() => {
res('2.1');
}, 100);
});
}
function runParallel(promises) {
// implementation here
}
for await (const results of runParallel([f1(), f2()])) {
console.log(results);
}
/**
* should output 2 lines:
*
* [undefined, "2.1"] // (after 100 ms)
* ["1.1", "2.1"] // (after 1000 ms)
*/
})();
async function* runParallel(promises) {
const result = Array(promises.length).fill(void 0);
const resolved = new Set();
promises.forEach((promise, index) => {
promise.then(value => {
result[index] = value;
resolved.add(promise);
});
});
while (promises.length !== resolved.size) {
await Promise.race(promises.filter(promise => !resolved.has(promise)));
yield result;
}
}
function runParallel(promises) {
const result = Array(promises.length).fill(void 0);
const resolved = new Set();
promises.forEach((promise, index) => {
promise.then(value => {
result[index] = value;
resolved.add(promise);
});
});
const iterator = {
next: async () => {
const done = resolved.size === promises.length;
if (done) {
return { done: true };
}
await Promise.race(promises.filter(promise => !resolved.has(promise)));
return {
value: result,
done: false
};
}
};
return { [Symbol.asyncIterator]: () => iterator };
}
@peter-leonov
Copy link

Neat!

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