Prisma GraphQL-Yoga: должны ли распознаватели быть асинхронными?

Я пытаюсь осмыслить Prisma и GraphQL, используя GraphQL-Yoga. Одна вещь, которая меня озадачила в резольверах. В примерах 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,
          })
        },

person Cerulean    schedule 12.03.2019    source источник


Ответы (1)


Во-первых, резолверы (могут) вернуть обещание. Им не обязательно, но в обоих примерах кода преобразователи возвращают обещание. Успокойтесь с обещаниями, в наши дни почти все асинхронные вещи выполняются с помощью обещаний!

Далее вам следует прочитать об асинхронных функциях в JavaScript. async / await - это синтаксический сахар для обещаний. Таким образом, они всегда возвращают обещание (даже если вы не используете await внутри).

Первый пример явно возвращает Promise. Второй пример делает то же самое, но неявно (также здесь не требуется await, но это снова сделало бы его явным). Оба примера становятся более интересными, если вы впоследствии фактически измените значение:

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 в вашем примере является необязательным (но только потому, что он следует за возвратом. Если вы посмотрите на второй пример, вы также можете понять, почему люди утверждают, что «асинхронный вид выглядит более синхронный »: избавляется от обратных вызовов.

person Herku    schedule 12.03.2019
comment
Еще мне очень помогло использование статической типизации: это заставляет меня задуматься о типе значения. Клиент Prisma также поставляется с типами для Flow и TypeScript! - person Herku; 12.03.2019