Node.js Node-GraphQL-Ad.user字段类型必须是输出类型,但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

在AdType中使用UserType似乎存在循环依赖性问题

这是我的用户类型文件:

这是我的AdType文件:

如果我尝试使用下面的代码,即使正确导入了用户类型,也会出现错误“Ad.user字段类型必须是Output type,但是get:undefined”

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。您的类别和子类别不一样,它们使用在调用时创建对象的函数定义。为什么只有一种类型是未定义的,是因为它们是解析模块的方式。我在一篇文章的编辑中写到了这一点。谢谢,这让我更清楚了一点。我不知道你是这样工作的。我非常感谢你的帮助!有没有比使用函数返回更优雅的方法来解决这个问题?