在NodeJS中存储来自多个MongoDB查询的数据

好吧,我觉得如果我复制我的整个node.js路由,那么你就可以看到我在说什么了。

我试图对我的MongoDB数据库(每天一个)进行多个查询。 查询运行良好,但是当他们触发callback时,我的增量variables已经增加了。

所以对于这个:

exports.graph = function(req, res) { function pad(num, size) { var s = num+""; while (s.length < size) s = "0" + s; return s; } database.collection('customerData', function(err, collection) { for (var i = 2; i < 18; i++) { sDay = pad(i, 2); eDay = pad(i + 1, 2); collection.find({ DATE: { $gte: sDay + 'APR13:00:00:00', $lt: eDay + 'APR13:00:00:00' } }, function(err, cursor){ cursor.toArray(function(err, data){ var counter = 0; for (var point in data) { trans = parseInt(data[point].Total_Transaction * 100); counter += trans; } console.log(i, counter / 100); }); }); } }); } 

我得到这样的输出:

 18 22023.29 18 24483.03 18 22644.11 18 23194.31 18 21560.99 18 23024.32 18 24384.93 18 23138.34 18 24400.63 18 28418.6 18 31691.65 18 31111.62 18 42358.74 18 38355.76 18 36787.52 18 42870.19 18 22023.29 18 22644.11 18 24483.03 18 23194.31 18 21560.99 18 23024.32 18 24400.63 18 23138.34 18 24384.93 18 28418.6 18 31691.65 18 31111.62 18 42358.74 18 38355.76 18 36787.52 18 42870.19 

这个(显然)并不理想 – 数据不一定会按照查询被解雇的顺序回来,所以对我来说找出哪些数据到哪里是很重要的。

我无法find一种方法来将我的算术结果以有意义的方式存储在查询callback中,以便稍后使用它。

有什么想法吗?

在一个侧面说明,不像你的例子,下面我的例子,你真的应该保存收集参考,而不是每当你需要使用它重新实例。

至于你的问题,只是将每个调用的逻辑包装在自己的函数中。 这样你创build一个闭包,记得每个具体的查询是哪一天。 下面我创build了一个例子,把所有的结果都放到一个对象中,然后当所有的查询都完成后,它将按顺序输出所有的结果。

 var _outstanding = 0, _results = {}; database.collection('customerData', function(err, collection) { for (var i = 2; i < 18; i++) { _outstanding++; getDay(collection, i, getDayCallback); } }); function getDay (collection, day, callback) { sDay = pad(day, 2); eDay = pad(day + 1, 2); collection.find({ ...query obj... }).toArray(err, data) { var counter = 0; if (!err) { for (var point in data) counter += parseInt(data[point].Total_Transaction * 100); } callback(err, day, counter); }); } function getDayCallback (err, day, count) { // ...actually handle any errors, of course... _results[day] = count; if (--_outstanding === 0) { //display the results in-order when done for (var i = 2; i < 18; i++) console.log(i, _results[i] / 100) } } 

在这个人为的例子中, getDaygetDayCallback可以很容易地组合成一个函数,但是在现实世界中,你很可能希望它们保持独立。 此外,不知道哪里218来自,但我猜他们不应该实际上被硬编码多次像我一样:)。

@布雷特的答案是100%正确的。

我想贡献一下,以显示如何通过最小的修改来转换您的代码以包含闭包。 由于闭包在这种情况下非常有用(如果可能会有助于查看模式)。

 exports.graph = function(req, res) { function pad(num, size) { var s = num+""; while (s.length < size) s = "0" + s; return s; } database.collection('customerData', function(err, collection) { for (var i = 2; i < 18; i++) { sDay = pad(i, 2); eDay = pad(i + 1, 2); collection.find({ DATE: { $gte: sDay + 'APR13:00:00:00', $lt: eDay + 'APR13:00:00:00' } }, (function(i){ //anonymous function which is sync-executed, bringing // 'i' to closure-scope. return function(err, cursor){ cursor.toArray(function(err, data){ var counter = 0; for (var point in data) { trans = parseInt(data[point].Total_Transaction * 100); counter += trans; } console.log(i, counter / 100); }); }); }(i)) } }); }