创建异步迭代器的最佳实践是什么?我应该使用异步生成器函数还是使用 Symbol.asyncIterator?
What is the best practice to create an async iterator? Should I use an async generator function or rather use Symbol.asyncIterator?
此代码按预期工作:
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()
不管我在main
函数中使用asyncIterable
还是asyncIterable2
,我总是得到相同的结果。定义我的可迭代对象的最佳做法是什么?是否有关于首选哪个选项的指南?为什么?
这是 same as for synchronous iterators:与手动实现迭代器对象相比,生成器函数更容易编写,也更容易正确。仅当您需要一些无法通过其他方式实现的非标准行为时才这样做。特别是使用异步生成器函数,您甚至可以免费获得正确的 next
调用队列,这确实让人头疼(您的 asyncIterable2
失败了 1 ).
迭代器最常见的实现是使 Symbol.asyncIterator
方法成为异步生成器方法:
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield* await getAsyncData();
},
};
1: const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()
- 中间没有任何 await
s - 将调用 getAsyncData
两次,因为两次调用中的 this.values == null
此代码按预期工作:
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()
不管我在main
函数中使用asyncIterable
还是asyncIterable2
,我总是得到相同的结果。定义我的可迭代对象的最佳做法是什么?是否有关于首选哪个选项的指南?为什么?
这是 same as for synchronous iterators:与手动实现迭代器对象相比,生成器函数更容易编写,也更容易正确。仅当您需要一些无法通过其他方式实现的非标准行为时才这样做。特别是使用异步生成器函数,您甚至可以免费获得正确的 next
调用队列,这确实让人头疼(您的 asyncIterable2
失败了 1 ).
迭代器最常见的实现是使 Symbol.asyncIterator
方法成为异步生成器方法:
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield* await getAsyncData();
},
};
1: const it = asyncIterable2[Symbol.asyncIterator](); it.next(); it.next()
- 中间没有任何 await
s - 将调用 getAsyncData
两次,因为两次调用中的 this.values == null