GraphQL解析器为何需额外参数?双参数及下划线参数疑问
Hey,我懂你这种卡在Resolver细节上的困惑!之前我刚接触GraphQL的时候也对着这两个参数懵了好久,咱们一步步拆解清楚:
一、先理清Resolver函数的参数结构
Resolver函数的标准签名其实是4个参数,但日常开发中最常用的是前两个:
const resolver = (parent, args, context, info) => { // 业务逻辑 }
你疑惑的“两个参数”就是这里的parent和args:
- parent(也常叫root):代表上一级Resolver返回的结果。比如你有嵌套查询
Query.user.posts,那么posts的Resolver里的parent就是userResolver返回的用户对象,你可以用它来关联查询用户的帖子。 - args:客户端发起请求时传入的参数,比如
Query.getUser(id: 123)里的id就会被封装在args.id里。
你之前遇到的undefined参数问题,大概率是搞反了参数顺序——比如误以为第一个参数是args,结果取到的是parent(顶层Query的parent通常是undefined),自然拿不到想要的参数。
二、下划线_参数的真实作用
你看到的下划线_,本质是占位符,用来明确表示“这个参数我不需要使用”。
举个实际场景:如果是顶层的Query字段(比如getUser),没有上一级的Resolver结果,所以parent参数对我们没用,但我们又需要用到第二个参数args。这时候不能直接只写一个参数(因为参数顺序是固定的),就用_占住第一个位置,既符合函数签名要求,又能清晰告诉其他开发者:“这个参数我不需要”。
比如正确的写法:
const getUser = (_, args) => { return db.users.find(user => user.id === args.id); }
要是你直接写成(args),那这里的args实际上会接收到parent的值(也就是undefined),真正的客户端参数会跑到第二个参数的位置,这时候你取args.id自然就是undefined——这估计就是你之前踩的坑!
另外,用_还能避免ESLint这类代码检查工具抛出“未使用参数”的警告,比写了parent却不用它要更规范。
三、再说说你用到的解构
你修复时用到了解构,比如:
const getUser = (_, { id }) => { return db.users.find(user => user.id === id); }
这里的{ id }是直接从args里解构出id字段,不仅代码更简洁,还能避免因为参数顺序搞错而拿错值的问题,结合_占位符,就完美解决了之前的undefined问题。
内容的提问来源于stack exchange,提问作者Angel

