【发布时间】:2017-09-23 02:36:05
【问题描述】:
我有一个关于在 GraphQL 客户端的解析函数中处理承诺的问题。传统上,解析器会在服务器上实现,但我在客户端上封装了一个 REST API。
背景和动机
给定解析器,例如:
const resolvers = {
Query: {
posts: (obj, args, context) => {
return fetch('/posts').then(res => res.json());
}
},
Post: {
author: (obj, args, _, context) => {
return fetch(`/users/${obj.userId}`)
.then(res => res.json());
.then(data => cache.users[data.id] = data)
}
}
};
如果我运行查询:
posts {
author {
firstName
}
}
Query.posts()/posts API 返回四个帖子对象:
[
{
"id": 1,
"body": "It's a nice prototyping tool",
"user_id": 1
},
{
"id": 2,
"body": "I wonder if he used logo?",
"user_id": 2
},
{
"id": 3,
"body": "Is it even worth arguing?",
"user_id": 1
},
{
"id": 4,
"body": "Is there a form above all forms? I think so.",
"user_id": 1
}
]
Post.author() 解析器将被调用四次以解析 author 字段。
grapqhl-js 有一个非常好的特性,从 Post.author() 解析器返回的每个承诺都将并行执行。
我已经能够使用 facebook 的 dataloader 库进一步消除使用相同
userId重新获取作者的问题。 但是,我想使用自定义缓存而不是dataloader。
问题
有没有办法防止Post.author() 解析器并行执行?在Post.author() 解析器中,我想一次获取authors 一个,检查我的缓存以防止重复的http 请求。
但是,现在从Post.author() 返回的 Promise 被排队并立即执行,所以我无法在每个请求之前检查缓存。
感谢您的任何提示!
【问题讨论】:
-
未来读者请注意:当我说
graphql-js解析器通过“并行”执行来做任何事情时,我错了。正如 Lee 下面所说,resolve 函数和它们返回的 promise 会急切地执行。在这种情况下,从Post.author()解析器返回的所有承诺同时处于“飞行中”,这使得我在上面尝试的缓存检查变得不可能。通过一些唯一键(id或url)来记忆请求是可行的方法,我将使用 DataLoader。
标签: graphql graphql-js apollo