1

我正在尝试使用 GraphQL-Yoga 围绕 Prisma 和 GraphQL。一件事让我对解析器感到困惑。在 Prisma 示例(https://github.com/prisma/prisma-examples/blob/master/node/graphql/src/index.js)中,数据库调用似乎是同步的,例如

 Mutation: {
    signupUser: (parent, { email, name }, context) => {
      return context.prisma.createUser({
        email,
        name,
      })
    },

但我见过其他必须await从 Prisma 返回的例子。不应该所有这些数据库访问调用都是异步的,比如

 Mutation: {
        signupUser: async (parent, { email, name }, context) => {
          return await context.prisma.createUser({
            email,
            name,
          })
        },
4

1 回答 1

4

首先,解析器(可以)返回一个承诺。他们不必这样做,但在您的两个代码示例中,解析器都会返回一个承诺。熟悉 Promise,现在几乎所有异步的事情都是用 Promise 完成的!

接下来,您应该阅读 JavaScript 中的异步函数。async/await 是 promise 的语法糖。因此,他们总是返回一个承诺(即使你没有await在里面使用)。

第一个示例显式返回一个 Promise。第二个示例执行相同但隐式的操作(此处也不需要等待,但这将使其再次显式)。当您之后实际修改值时,这两个示例都变得更加有趣:

signupUser: (parent, { email, name }, context) => {
  return context.prisma.createUser({
    email,
    name,
  }).then(user => {
    return { ...user, isCool: user.friends > 5 };
  });
}
// vs. async function
signupUser: async (parent, { email, name }, context) => {
  const user = await context.prisma.createUser({
    email,
    name,
  };
  return { ...user, isCool: user.friends > 5 };
}

语法糖意味着它背后没有实际的新语言特性。通常,编译器在编译之前首先对语法进行脱糖(尤其是在函数式语言中)。作为一种心智模型,您可以想象将异步函数重写为承诺形式。这将使他们更容易理解为什么他们总是返回承诺以及他们实际在做什么。在掌握了这个概念之后,您将理解这两个示例实际上都是异步的,并且await您示例中的同步”:它摆脱了回调。

于 2019-03-12T17:56:27.073 回答