Reputation: 10657
I have an async iterator like this:
async function* getLines() {
for (let index = 0; index < 10; index++) {
const response = await fetch('/resource/' + index);
const data = await response.text();
yield data;
}
}
I am able to consume it using for await
:
let source = '';
for await (const line of getLines()) {
console.log('line');
source += line + '\n';
}
return source;
But I wonder if there is a way to use something like Array.from
or [...]
to achieve the same joining of items from an async iterator to a string.
Array.from(await getLines())
nor [...getLines()]
make sense by themselves as the generator itself is not to be awaited by the individual items, like in the for await
construct. Is there anything like Array.fromAwait(getLines())
or is that something I have to roll on my own like in the example where I use for await
?
Upvotes: 7
Views: 1288
Reputation: 25930
These days, it can be much simpler, with the help of iterables, and the variety of libraries that support them.
The example below is based on one such library, called iter-ops:
import {pipeAsync, map, reduce, wait} from 'iter-ops';
const indexes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; // your resource id-s
const i = pipeAsync(
indexes,
map(a => fetch('/resource/' + a).then(r => r.text())),
wait(), // resolve each request
reduce((r, c) => r + '\n' + c)
); //=> AsyncIterable<string>
// test:
(async function () {
const source = await i.first; // iterate, and wait for the first value
console.log(source); // all the lines joint together
})();
It is also the fastest way to convert a list of source id-s into the final data.
P.S. I am the author.
Upvotes: 0
Reputation: 160
You could use IX (interactive extension) it is a library created by the RxJs community that has the same operators in RxJs but is used with sync and async iterators
Upvotes: 0
Reputation: 276506
The current specification does not support operators like .reduce
on async iterators and unless you are on Node (in which case you can do AsyncIterator -> Readable.from -> async iterator) you will have to use a user-land library like axax.
There is a tc39 proposal toadd iterator helpers. With those you will be able to do:
const source = await getLines().reduce((l, cur) => l + cur);
It is currently stage 2 and you can use a polyfill.
Upvotes: 4