获取mongodb数据到nodejs数组?

时间:2013-09-16 07:26:49

标签: node.js mongodb callback mongojs

我无法将mongodb数据导入nodejs数组,如下所示:

测试数据库:

{
  "supportTicket" : "viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf",
  "msgId" : 1379304604708.0,
  "username" : "Guest-OSsL2R",
  "message" : "hello",
  "_id" : ObjectId("5236849c3651b78416000001")
}

的NodeJS:

function _getMsg(st, callback) {
    db.test.find({ supportTicket: st }).toArray(function (err, docs) {
        callback(docs);
    });
}

var nodeArr = _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
    console.log(res); // --> res contain data and printed ok
    return res; 
});

console.log('return data: ' + nodeArr )  // --> However, nodeArr  is undefined.

结果如下:

return data: undefined
return data: undefined
[ { supportTicket: 'viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf',
    msgId: 1379304604708,
    username: 'Guest-OSsL2R',
    message: 'dhfksjdhfkj',
    _id: 5236849c3651b78416000001 } ]
[ { supportTicket: 'viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf',
    msgId: 1379304604708,
    username: 'Guest-OSsL2R',
    message: 'dhfksjdhfkj',
    _id: 5236849c3651b78416000001 } ]

问题是:如何从测试数据库获取数据并将数据分配给nodeArr?

4 个答案:

答案 0 :(得分:5)

正如您所注意到的,控制台确实显示了_getMsg调用的结果。

_getMsg不会返回值,因此当您尝试将nodeArr变量分配给结果时,它会获得undefined的值,因为没有return价值。即使您将其更改为返回值,在调用函数时也不会返回结果。

find的调用与大多数NodeJ和MongoDb驱动程序是异步的。因此,它不会立即返回,这就是为什么在函数完成时需要回调信号的原因。如果没有这种模式,函数调用者将永远不会收到结果。

你已经定义了回调:return res。这会将结果返回给发起呼叫的函数:callback(docs)。虽然技术上没有任何问题,但没有理由这样做,因为调用者已经有了结果。这只是忙碌的工作。

另外,我要小心在NodeJS中声明全局范围内的变量。对于异步行为(并且只有一个线程为所有连接执行所有工作),您可能会发现在没有检查的情况下,在任何给定时刻难以确定全局变量的值。

function _getMsg(st, callback) {
    db.test.find({ supportTicket: st }).toArray(function (err, docs) {
        callback(docs);
    });
}

_getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
    console.log(res); // --> res contain data and printed ok
    var nodeArr = res;  // just moved the nodeArr declaration to function scope
    // *** do next step here, like send results to client
});

如果您要将结果发送回客户端,在调用_getMsg内部,您可能会遇到类似这样的事情(假设它处于处理http request的上下文中):< / p>

response.writeHead(200, { 'Content-Type': 'application/json'});
response.write(JSON.stringify(nodeArr));
response.end();

这可能包含在像这样的基本内容中:

var http = require('http');
http.createServer(function (req, response) {
    // all requests return the results of calling _getMsg
    // this function won't return until the callback completes
    _getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (nodeArr) {        
        response.write(JSON.stringify(nodeArr));
        response.end();
    });
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

答案 1 :(得分:4)

你可以这样做:

var nodeArr;
function _getMsg(st, callback) {
    db.test.find({ supportTicket: st }).toArray(function (err, docs) {
        callback(docs);
    });
}

_getMsg('viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf', function (res) {
    console.log(res); 
    nodeArr = res; 
});

console.log('return data: ' + nodeArr ) 

但通常是可怕的想法,在您的情况下,console.log仍会显示为undefined。这是因为在查询完成时将执行asignation,但节点仍将执行代码,直到发生这种情况。

通常情况下,您应该在_getMsg的回调中使用数据并执行您想要执行的任何操作。在大多数情况下,这是安全的工作方式。

答案 2 :(得分:1)

您需要了解异步和同步流之间的概念。

db.test.find({ supportTicket: st }).toArray(function (err, docs) {
  if (err) throw err;
  nodeArr = docs;
});

答案 3 :(得分:0)

logindata.find({名称:req.body.username})。select()。exec(function(err,data){ })