Node.js Node-GraphQL-Ad.user字段类型必须是输出类型,但get:undefined
在AdType中使用UserType似乎存在循环依赖性问题 这是我的用户类型文件: 这是我的AdType文件: 如果我尝试使用下面的代码,即使正确导入了用户类型,也会出现错误“Ad.user字段类型必须是Output type,但是get:undefined”Node.js Node-GraphQL-Ad.user字段类型必须是输出类型,但get:undefined,node.js,output,undefined,graphql,circular-dependency,Node.js,Output,Undefined,Graphql,Circular Dependency,在AdType中使用UserType似乎存在循环依赖性问题 这是我的用户类型文件: 这是我的AdType文件: 如果我尝试使用下面的代码,即使正确导入了用户类型,也会出现错误“Ad.user字段类型必须是Output type,但是get:undefined” import { UserType } from '../User/user.graphql.model' import { UserSchema } from '../User/user.mongoose.model' const u
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内控制台log UserType,它会显示undefined,但当我将其用作:
//------------------------------
// 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
它按预期工作,只是不允许我提取代码来分离常量。
我导入和使用的所有其他类型都与预期的工作方式相同,将广告导入到用户中也很有效,但将用户导入到广告中似乎是失败的。这两个版本的代码基本相同,只是信息不同
我已经在使用字段:()=>({})来延迟加载字段,以避免循环依赖的问题,所以这个问题真的很困扰我
但你做得不对。Javascript没有延迟计算。这意味着user
的值不是在调用函数时确定的,而是在计算const
变量定义时确定的。此时,变量UserType
不包含任何值,因此未定义。调用函数时需要进行对象定义。如果仍然不清楚,我可以提供详细说明您的类型是如何解析的
尝试内联定义用户类型或将其设置为函数:
const user = () => ({ type: UserType, /* ... */ })
export const AdType = new GraphQLObjectType({
name: 'Ad',
fields: () => ({
id,
user: user(),
title,
views,
availability,
我不知道为什么要将字段拉入单独的常量中,您的代码看起来并没有那么大,以至于无法提高可读性,但我当然可能是错的
好的,让我们看看模块是如何解析的。为了使这更容易,我使用CJS,因为您很可能会以任何方式向下传输代码,而ES模块只是缓慢地到达节点
// 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
/* ... */
})
我已经在使用字段:()=>({})来延迟加载字段以避免循环依赖的问题,所以这个问题真的很困扰我。我的意思是我在字段中使用()=>({}),因为我在使用字段时代码已经中断:{user:..}语法,因为它导致了循环依赖,所以我就这样解决了。我不明白的是,为什么只有UserType会出现这个问题,而不是CategoryType、SubcategoryType和其他以UserType相同的方式导入的类型。我决定这样构造我的代码,因为我希望代码会增长很多,所以我不想以后陷入混乱的代码中。是的,但是如果不在函数调用内部引用,那么仅仅使用函数参数并不能解决问题。完成变量解析需要时间,但是如果你需要的话,我可以在答案中写下来。我不确定我是否完全理解你在最后的评论中想说什么。定义constuser=()=>({type…})是有效的,我理解它是有效的,因为它在constadtype=..时执行代码。。。被执行。我不明白的是,为什么只有UserType会产生这个问题。在用户模型中,我以同样的方式引用AdType,它不会产生任何问题。我还使用CategoryType和SubcategoryType,它们的结构是相同的,只是数据不同,而且没有bug。您的类别和子类别不一样,它们使用在调用时创建对象的函数定义。为什么只有一种类型是未定义的,是因为它们是解析模块的方式。我在一篇文章的编辑中写到了这一点。谢谢,这让我更清楚了一点。我不知道你是这样工作的。我非常感谢你的帮助!有没有比使用函数返回更优雅的方法来解决这个问题?