【发布时间】:2019-03-05 18:10:59
【问题描述】:
我正在使用Sequelize 访问我的关系数据库并在GraphQL 解析器中提供结果。 Sequelize 框架内的查询是异步执行的 (bluebird)。为了缓冲大型结果集并避免服务器上的高内存需求,例如请求了数百万条记录,我想在我的解析器中返回一个迭代器。考虑一下这个简化的要点:
// root resolver
function allPersons(...) {
[...]
return {
nextId: 1,
maxId: 10000000,
[Symbol.iterator]: () => { return this },
next: function() {
let nextRes = { done: true, value: null }
if (this.nextId <= this.maxId) {
nextRes.value = sequelize.models.person.findById(this.currId)
nextRes.done = false
this.nextId = this.nextId + 1
}
return nextRes
}
}
上述方法有效,因为 Sequelize 构造的 Promise 返回为 next() 的 value。当 this value-Promise 被解析时,它会从底层关系数据库中获取一条记录。因此,我同步构造异步数据获取。这只有效,因为每个单独的提取都独立于所有其他提取。特别是在执行下一个之前,不需要awaited 单个提取。但是,逐行获取关系数据库在技术上效率低下,实际上是一种反模式。因此,我想实现一个缓冲区,它可以获取 10k 行的批次,为它们提供服务,直到批次为空,然后再获取下一个。但是,由于随后引入了异步事件的依赖关系,要实现这一点,需要一个异步迭代器(Symbol.asyncIterator)。
我需要做什么才能使GraphQL's reference implementation(graphql-js 和/或 express-graphql)接受异步迭代器?
请注意,我想避免使用Apollo GraphQL。
或者 Object-Stream 是一种可能的解决方案吗?
我们将不胜感激。
【问题讨论】:
标签: node.js asynchronous graphql graphql-js