This code works as expected:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getAsyncData() {
await sleep(1000); // simulate database/network delay...
return [1, 2, 3, 4, 5]; // ...then return some data
}
const asyncIterable = (async function* filterAsyncData() {
const items = await getAsyncData();
for (const item of items) {
yield item;
}
})();
const asyncIterable2 = {
[Symbol.asyncIterator]() {
return {
values: null,
idx: 0,
async next() {
if (this.values === null) {
this.values = await getAsyncData();
}
if (this.idx < this.values.length) {
this.idx = this.idx + 1;
return Promise.resolve({ value: this.values[this.idx - 1], done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
async function main() {
for await (const filteredItem of asyncIterable) {
console.log(filteredItem);
}
}
main()
It does not mather if I use asyncIterable
or asyncIterable2
in the main
function, I always get the same result. What is the best practice to define my iterable? Are there any guidelines about which option is preferred? Why?
It's the same as for synchronous iterators : generator functions are much easier to write, and easier to get correct, than implementing the iterator object manually. Do this only if you need some non-standard behaviour that cannot be achieved otherwise. With asynchronous generator functions specifically, you even get the proper queueing of next
calls for free, which is a real headache to get right (your asyncIterable2
fails this 1 ).
The most common implementation of iterables is to make the Symbol.asyncIterator
method an async generator method:
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield* await getAsyncData();
},
};
1: const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()
const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()
const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()
- without any await
s in between - will call getAsyncData
twice, because this.values == null
in both calls
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.