我在 AdType 中使用 UserType 时似乎遇到了循环依赖问题。
这是我的用户类型文件:UserType
这是我的 AdType 文件:AdType
如果我尝试使用下面的代码,即使我正确导入了 UserType,也会收到错误“Ad.user 字段类型必须是输出类型,但得到:未定义”。
import { UserType } from '../User/user.graphql.model'
import { UserSchema } from '../User/user.mongoose.model'
const user = {
type: UserType,
resolve(parentValue, args) {
return UserSchema.findById(parentValue.user);
}
};
//------------------------------
// Ad Type
//------------------------------
export const AdType = new GraphQLObjectType({
name: 'Ad',
fields: () => ({
id,
user,
title,
views,
availability,
... more code
如果我在导入 AdType 后尝试在 AdType 中控制台记录 UserType,它会显示未定义,但当我将其用作:
//------------------------------
// Ad Type
//------------------------------
export const AdType = new GraphQLObjectType({
name: 'Ad',
fields: () => ({
id,
user: {
type: UserType,
resolve(parentValue, args) {
return UserSchema.findById(parentValue.user);
}
},
title,
... more code
它按预期工作,只是不允许我提取代码来分隔常量。 我以相同方式导入和使用的所有其他类型都按预期工作,将广告导入用户也可以,但将用户导入广告似乎会中断。两者的代码基本上相同,只是信息不同。
最佳答案
I am already using fields: () => ( { } ) to lazily load fields to avoid problems with circular dependencies, so this problem is really banging against my head.
但是你做得不对。 JavaScript 没有惰性求值。这意味着 user
的值不是在调用函数时确定的,而是在对 const
变量定义求值时确定的。此时,变量UserType
没有任何值,因此未定义。您的对象定义需要在调用函数时进行。如果仍然不清楚,我可以详细说明您的类型是如何解析的。
尝试内联定义用户类型或将其设为函数:
const user = () => ({ type: UserType, /* ... */ })
export const AdType = new GraphQLObjectType({
name: 'Ad',
fields: () => ({
id,
user: user(),
title,
views,
availability,
我不确定为什么你将字段放入单独的常量中,你的代码看起来并没有那么大,它提高了可读性,但当然我可能是错的。
好吧,让我们看看模块是如何解析的。为了使这更容易,我使用 CJS,因为你很可能无论如何都会将代码转译下来,而 ES 模块只是慢慢地进入 Node 。
// user.graphql.model.js
const adModule = require('ad.graphql.model.js');
// Node tries to resolve ad.graphql.model.js
const userModule = require('user.graphql.model.js');
// Ups, this one has been resolved already and required this as dependency.
// We have no other choice than to assign an empty object here
// userModule is {}
const user = {
type: userModule.UserType, // undefined
resolve(parentValue, args) {
return UserSchema.findById(parentValue.user);
}
};
// finish this module and return to user.graphql.model.js
// adModule now contains the resolved module
const adModule = require('ad.graphql.model.js');
// finish module and replace {} with actual module content in ad.graphql.model.js
// userModule contains UserType
const userModule = require('user.graphql.model.js');
const ads = {
type: new GraphQLList(asModule.AdType), // GraphQLObjectType
}
// Now your Schema does build/inits itself after the config has been specified
// (and all modules have been resolved)
// imagine user being a function now taht is called on Schema init
const user = () => ({
type: userModule.UserType, // GraphQLObjectType
/* ... */
})
关于node.js - Node - GraphQL - Ad.user 字段类型必须是输出类型,但得到 : undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48286657/