context.done在handler' graphql'中调用了两次

时间:2018-05-13 17:44:37

标签: node.js aws-lambda graphql serverless

尝试根据https://github.com/serverless/serverless-graphql/blob/master/app-backend/dynamodb/handler.js创建项目。代码效果很好,但出于某种原因,我总是收到一条日志警告,告诉我context.done called twice

import { graphqlLambda, graphiqlLambda, LambdaHandler } from 'apollo-server-lambda'
import lambdaPlayground from 'graphql-playground-middleware-lambda'
import { makeExecutableSchema } from 'graphql-tools'

import { resolvers } from './resolvers'

const typeDefs = require('./schema.gql')
const schema = makeExecutableSchema({ typeDefs, resolvers, logger: console })

export const graphqlHandler: LambdaHandler = async (event, context) => {
  const handler = graphqlLambda({ schema })
  return handler(event, context, (error: Error | undefined, output: any) => {
    output.headers['Access-Control-Allow-Origin'] = '*'
    context.done(error, output)
  })
}

export const playgroundHandler = lambdaPlayground({
  endpoint: '/graphql',
})

export const graphiqlHandler: any = graphiqlLambda({
  endpointURL: '/graphql',
})

此代码给出了以下结果:

Serverless: POST /graphql (λ: graphql)
Serverless: [200] {"statusCode":200,"headers":{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"},"body":"{\"data\":{\"getUserInfo\":\"ads\"}}"}

Serverless: Warning: context.done called twice within handler 'graphql'!

更奇怪的是,如果我评论context.done来电,我会收到以下输出(呼叫会按预期停止):

Serverless: POST /graphql (λ: graphql)

Serverless: Warning: context.done called twice within handler 'graphql'!

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题。如果您不打算使用await,请尝试删除函数中的async。看起来该函数一直等待,直到不存在异步时才调用callback或context.done。但是它始终使用async关键字运行。但是,当它运行通过时,函数结束时返回的任何内容都将调用context.done。这是一个示例工作代码。

让我也分享来自aws lambda的两个关于callbackcontext的有用资源。

export const handler = (
  {
    headers,
    pathParameters: pathParams,
    queryStringParameters: queryParams,
    body,
  },
  context,
  callback
) => {
  context.callbackWaitsForEmptyEventLoop = false;

  const data = JSON.parse(body);
  const params = {
    TableName: process.env.EVENT_TABLE,
    Item: {
      id: uuid.v4(),
      title: data.title,
      creationDate: new Date().getTime(),
    },
  };

  dynamoDb.put(params, (err, data) => {
    if (err) {
      callback(err);
    }
    callback(null, {
      statusCode: 200,
      body: JSON.stringify(data),
    });
  });
};

答案 1 :(得分:0)