javascript - 生成器可以使用异步函数吗?
问题描述
我正在从后端服务获取数据,一次 20 个结果。我想隐藏这个实现细节并创建一个生成器,只要我需要它们(当它们可用时),它就会一直返回记录。
天真的实现:
function* getEndlessRecords(fetchingFunction) {
const batchSize = 20;
// endless loop:
for (let offset = 0; true; offset += batchSize) {
fetchingFunction(offset, batchSize)
.then(records => {
for (let i=0; i < records.length; i++) {
yield records[i]; // THIS DOESN'T WORK!!!
}
})
}
}
(可能有错别字 - 这是简化的代码)
我理解为什么这不起作用(yield
适用于最里面的函数),但是我似乎找不到围绕异步函数创建生成器的好方法。
生成器是否可以使用异步函数的输出?
解决方案
从 ES2018 开始,您可以使用异步生成器函数:
async function* getEndlessRecords(fetchingFunction) {
const batchSize = 20;
// endless loop:
for (let offset = 0; true; offset += batchSize) {
const records = await fetchingFunction(offset, batchSize);
for (let i=0; i < records.length; i++) {
yield records[i];
}
}
}
您将在使用(not ) 的async
函数中使用它:for-await-of
for-of
for await (const value of getEndlessRecords(/*...*/)) {
// Do something with `value`
}
...或者只是通过调用它的next
方法并等待结果:
let g = getEndlessRecords(/*...*/);
let result;
while (!(result = await g.next()).done) {
console.log(result.value);
}
...或者当然,在非函数中,async
您将使用then
.g.next()
在 ES2018 的异步生成器函数语法之前,您必须手动编码生成器而不是使用function*
语法。这样做可以说是正确的(不允许对%GeneratorPrototype%进行任何扩展)相当容易。正确地这样做是相当尴尬的,因为%GeneratorPrototype%没有可公开访问的符号,您必须去发现它。
推荐阅读
- java - 关于 String 和返回对象的基本类问题
- google-maps - Flutter 谷歌地图插件不工作,不显示谷歌地图
- html - 三个文本正文未与行内块对齐
- django - Azure Docker Django sqlite3 未部署
- 3d - 如何在我们自己的相机-LiDAR 设置中使用 KITTI 3D 对象检测方法,我们只有一个校准集?
- javascript - 从对象中删除空对象、数组、字符串或整数
- flutter - 使用身份验证中的用户 ID 在流构建器中显示文本
- java - 带有对象列表的多个列表
- c# - C#中的Excel IsError等效函数
- node.js - 如何在 express 中创建自定义中间件?