如何在需要return语句的GraphQL解析器中调用异步node.js函数?

时间:2017-05-12 05:29:45

标签: javascript node.js asynchronous graphql graphql-js

graphql.org/graphql-js上提供的用于创建简单GraphQL实现的Hello World示例如下:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        hello: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    hello: () => {
        return 'Hello World!';
    }
};

// Run the GraphQL query '{ hello }' and print out the response
graphql(schema, '{ hello }', root).then((response) => {
    console.log(response);
});

我正在尝试在解析器中运行异步函数,例如数据库调用,而我似乎无法弄清楚如何使其工作:

我正在尝试做什么:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        getData((data) => {
            return data;    // Returns from callback, instead of from resolver
        }
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});

我曾试图使用promises,但似乎没有办法在不进行回调的情况下逃避承诺。我还尝试了各种方法来包装异步getData函数以强制它同步,但最终必须从异步函数返回一个值,同样的问题。我觉得这不是很复杂,我的意思是GraphQL-JS是由Facebook编写的。

1 个答案:

答案 0 :(得分:10)

所以这个问题在你弄明白之后就变成了你觉得非常愚蠢的问题之一,但是由于我花了多长时间挣扎,我会回答我自己的问题,所以其他人可以从中受益。

事实证明,GraphQL解析器函数必须返回值或解析为该值的promise 。所以我试图用这样的东西做什么:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        getData((data) => {
            return data;    // Returns from callback, instead of from resolver
        }
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});

可以这样做:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

let promiseData = () => {
    return new Promise((resolve, reject) => {
        getData((data) => {
            resolve(data);
        });
    });
};

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        return promiseData();
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});