如何 return 来自回调的值?

How to return a value from callback?

我正在尝试将 GraphQL (Apollo/Node.js) 和 gRPC (Go) 粘合在一起。到目前为止,我可以在他们之间进行通信。

但是,我无法 return 从 gRPC 客户端回调中创建用户值。

这是用户架构;

// schema.ts

import {gql} from 'apollo-server-express'

const schema = gql`
  type Mutation {
    addUser(input: AddUser): User
  }

  type User {
    id: ID!
    email: String
  }

  input AddUser {
    email: String!
    password: String!
  }
`

export default schema

这是解析器;

// resolver.ts

import {add} from '../client'

const resolver = {
  Query: {
    users: () => console.log('in progress'),
  },
  Mutation: {
    // addUser: (_: any, {input}: any) => add(input),

    // This successfully logs the `res`
    // addUser: (_: any, {input}: any) => add(input, (res: any) => console.log('Logged from resolver >', res)),

    // This returns null in mutation
    addUser: (_: any, {input}: any) => add(input, (res: any) => {
      return res
    }),
  }
}

export default resolver

这是 gRPC 客户端,return未定义。

// client.ts

export async function add(input: any) {

  // Confirmed created in database
  client.addUser({
    email: input.email,
    password: input.password
  }, (_err: any, res: any) => {

    // Successfully logs `res`
    console.log('Logged res here > ', res)

    return res
  })
}

请帮帮我。


编辑:

我也试过回调函数:

export async function add(input: Input, callback: any) {
  try {
    await client.addUser({
      email: input.email,
      password: input.password
    }, (_err: any, res: any) => {
      console.log('Logged res here > ', res)
      return callback(res)
    })
  } catch (error) {
    console.log(error);
  }
}

突变中仍然 return 为空:

    addUser: (_: any, {input}: any) => add(input, (res: any) => {
      return res
    }),

GraphQL 解析器应该 return 适当类型的值,否则 Promise 将解析为该值。 Callbacks 和 Promises 都是异步处理代码的方式,但是它们不兼容。

不清楚您使用的是什么客户端库,但大多数使用回调的库现在也公开了一个 Promise API——如果您的库公开了,您应该使用它。如果那不是一个选项,您应该 wrap the callback with a Promise。类似于:

const resolver = {
  Mutation: {
    addUser: (_: any, {input}: any) => new Promise((resolve, reject) => {
      add(input, (res) => {
        resolve(res)
      })
    }),
  },
}

请注意,如果您的回调传递了错误,您应该确保调用 reject 而不是调用 resolve