我正在使用graphql和mongodb(mongoose)构建一个快速JS应用程序。我正在使用facebooks Dataloader批处理和缓存请求。
除了这个用例外,它的工作非常好。
我有一个充满用户帖子的数据库。每个帖子都包含用户ID以供参考。当我打电话返回数据库中的所有帖子时。帖子很好,但如果我试图让每个帖子中的用户。具有多个帖子的用户将仅返回单个用户,因为缓存了第二个用户的密钥。因此来自用户“x”的2个帖子(键)将仅返回1个用户对象“x”。
然而,Dataloader必须返回与其收到的密钥相同数量的承诺。
它有一个选项可以将缓存指定为false,因此每个密钥都会发出请求。但这似乎不适用于我的用例。
很抱歉,如果我没有很好地解释这一点。
这是我的graphql请求
query {
getAllPosts {
_id // This is returned fine
user {
_id
}
}
}
返回错误:
DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.
答案 0 :(得分:2)
您是否尝试批量发布密钥[1, 2, 3]
并希望获得用户结果[{ user1 }, {user2}, { user1 }]
?
或者您是否尝试批量处理用户密钥[1, 2]
并希望获得发布结果[{ post1}, {post3}] and [{ post2 }]
?
似乎只有在第二种情况下才会遇到键长不同于结果数组长度的情况。
要解决第二个问题,你可以在sql中执行类似的操作:
const loader = new Dataloader(userIDs => {
const promises = userIDs.map(id => {
return db('user_posts')
.where('user_id', id);
});
return Promise.all(promises);
})
loader.load(1)
loader.load(2)
所以你返回[[{ post1}, {post3}], [{ post2 }]]
哪个dataloader可以解包。
如果你这样做了:
const loader = new Dataloader(userIDs => {
return db('user_posts')
.where('user_id', [userIDs]);
})
loader.load(1)
loader.load(2)
您将获得[{ post1}, {post3}, { post2 }]
,因此会收到错误:the function did not return a Promise of an Array of the same length as the Array of keys
不确定上述内容是否相关/有用。如果您能提供批量加载功能的片段,我可以修改