0

我已将 DataLoaders 集成到我的 graphQL 请求中,但由于某种原因,缓存是跨请求记忆的。我可以读到在 ApolloServer 配置中将函数传递给上下文应该在每个请求上创建一个新的上下文,但由于某种原因,即使在那时,DataLoaders 也会被记忆。

这是我的代码

阿波罗配置:

export default new ApolloServer({
  resolvers,
  typeDefs,
  context: ({ req, res }) => generateContext(req, res)
});

生成上下文:

const generateContext = (req: Express.Request, res: Express.Response) => ({
  ...generateLoaders(),
  res,
  req
});

生成加载器:

import * as questionLoaders from './questionLoaders';

const generateLoaders = () => ({
  questionLoaders
});

问题加载器:

const batchQuestions = async (ids: number[]) => {
  const questions = await Question.query().findByIds(ids);
  return ids.map((id) => questions.find((q) => q.id === id));
};

export const questionLoader = new dataloader((ids: number[]) => batchQuestions(ids));
4

1 回答 1

3

您只需调用DataLoader一次构造函数,然后将生成的 DataLoader 实例导出为常量。即使在每个请求上调用您的上下文函数,它也会使用导入的值,该值始终是相同的 DataLoader 实例。更改您的导出,使其成为一个函数:

export const createQuestionLoader = () => new dataloader((ids: number[]) => batchQuestions(ids));

然后你可以导入它并调用里面的函数context

import { createQuestionLoader } from '...'

const generateContext = (req: Express.Request, res: Express.Response) => ({
  QuestionLoader: createQuestionLoader(),
  res,
  req
});
于 2020-02-11T15:47:53.367 回答