Đức*_*yễn 5 callback mongodb node.js mongojs
我在将mongodb数据放入nodejs数组时遇到问题,如下所示:
测试数据库:
{
"supportTicket" : "viT8B4KsRI7cJF2P2TS7Pd0mfqaI5rtwf",
"msgId" : 1379304604708.0,
"username" : "Guest-OSsL2R",
"message" : "hello",
"_id" : ObjectId("5236849c3651b78416000001")
}
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
结果如下:
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 } ]
Run Code Online (Sandbox Code Playgroud)
问题是:如何从测试数据库中获取数据并将数据分配给nodeArr?
你可以这样做:
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 )
Run Code Online (Sandbox Code Playgroud)
但通常这是一个糟糕的主意,在你的情况下,它console.log
仍然会显示为undefined
。这是因为分配将在查询完成时完成,但节点仍将执行代码,直到查询完成为止。
通常你应该使用数据并在 的回调中做任何你想做的事情_getMsg
。在大多数情况下,这是安全的工作方式。
如您所见,控制台确实显示了_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
});
Run Code Online (Sandbox Code Playgroud)
如果您将结果发送回客户端,则在调用内部_getMsg
可能有类似以下内容(假设它是在处理http的上下文中request
):
response.writeHead(200, { 'Content-Type': 'application/json'});
response.write(JSON.stringify(nodeArr));
response.end();
Run Code Online (Sandbox Code Playgroud)
可以将其包装成这样的基本内容:
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/');
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13134 次 |
最近记录: |