NodeJS和Neo4j的异步行为问题

时间:2013-07-07 03:37:17

标签: javascript node.js neo4j asynchronous

我是一名自学新手程序员,致力于使用Angular.js,Node.js和图形数据库neo4j的简单Web应用程序。现在我正在尝试获得一个非常基本的查询来执行并将数据返回给客户端。执行后,我收到一个关闭服务器的错误。

接收到get请求后执行以下函数:

exports.test = function (req, res) {
var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://localhost:7474');
var query = [
    'MATCH n',
    'RETURN n.name, n, labels(n)'
];
db.query(query, function (err, results) {
    if (err) {throw err};
    var data = results.map(function(result) {
            return result;
    });
    res.send(data)
}
)};

我在控制台日志中收到以下错误:java.lang.ClassCastException:java.util.ArrayList无法强制转换为java.lang.String

(如果证明有用,我可以提供整个日志)

我非常感谢任何见解。

2 个答案:

答案 0 :(得分:2)

您的错误原因是您将数组作为查询传递:

var query = [
    'MATCH n',
    'RETURN n.name, n, labels(n)'
];
db.query(query, function (err, results) { ... }

那应该是一个字符串,因此是java.lang.ClassCastException

所以你应该加入query数组使它成为一个字符串,或者不要使用数组:

// solution 1
var query = [
    'MATCH n',
    'RETURN n.name, n, labels(n)'
].join(' ');

// solution 2
var query = 'MATCH n RETURN n.name, labels(n)';

此外,这段代码有点多余:

var data = results.map(function(result) {
  return result;
});
res.send(data);

为什么不使用它?

res.send(results);

答案 1 :(得分:1)

实际上没有问题。这就是Node.js的工作方式。 Node.js实际上是一种异步语言,这意味着它将执行下一个语句而不等待前一个语句完全执行。目前,你的代码假设变量{{1} }将在与data一起使用之前定义。然而,这种情况并非如此。实际发生的是:

  1. 您的代码开始映射查询的结果。变量res.send()尚未定义。
  2. 您执行的方法需要data,但尚不存在。
  3. 您的data变量是通过data
  4. 中的回调定义的

    这就是NodeJS的异步行为的工作原理。基本上,回调(方法中的函数)执行LAST。因此,您可能希望将results.map()语句放在回调中,就像这样(请注意,定义res.send()变量首先是无用的,因为它依赖于其值的回调):

    data

    这是一个艰难的概念,包裹你的头...花了我一个星期。如果您还有其他问题,请与我们联系。