proposal-async-iterator-helpers
proposal-async-iterator-helpers copied to clipboard
Async iterator from iterator of promises via racing
This proposal will include Iterator.prototype.toAsync
, which takes a potentially-infinite iterator of values. Calling .next()
on the result will call .next()
on the underlying thing, await
the result and yield it - basically lifting { done: boolean, value: Promise<T> }
to Promise<{ done: boolean, value: T }>
.
Another way to do it is to take a finite iterator of values, await
all of them simultaneously, and yield the results in the order in which they settle. Basically:
async function* raced(promises) {
while (promises.length > 0) {
let [p, i] = await Promise.race(promises.map((p, i) => p.then(v => [v, i])));
promises.splice(i, 1);
yield p;
}
}
let sleep = ms => new Promise(res => setTimeout(res, ms));
let promises = [sleep(200).then(x => 2), sleep(100).then(x => 1), sleep(300).then(x => 3)];
for await (let item of raced(promises)) {
console.log(item);
}
// prints 1, 2, 3
I'm sure this has been proposed before, but I can't find it.
It probably doesn't make sense to put it in this version of the proposal, but since it is similar in signature to toAsync
I wanted to mention it anyway.
This is basically sync.toAsync().bufferUnordered(N)
with an N
set to the length of sync
, so it may not make sense to include if we end up adding bufferUnordered
.