在我的Mongodb数据库中,我有一个这种类型的文档集(Mongoose描述):
{ colour: String, addedDate: {type: Date} }
例如,这是一个数据样本:
{colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'}
{colour: 'red', addedDate: '2014-09-24T23:00:00.000Z'}
{colour: 'white', addedDate: '2013-11-24T23:00:00.000Z'}
{colour: 'red', addedDate: '2012-09-24T23:00:00.000Z'}
{colour: 'white', addedDate: '2014-01-24T23:00:00.000Z'}
{colour: 'yellow', addedDate: '2014-09-24T23:00:00.000Z'},
我想获得某些颜色(在数组中指定),包含最新' addedDate'的文档。并将结果存储在数组中。
这是我的代码:
var Colour = require('../app/models/colour');
var colours = ['white', 'red'];
var results = [];
for (var i = 0; i<colours.length; i++) {
var name = colours[i];
(function(output, colour_name) {
Colour.find({name: colour_name})
.sort('-addedDate').limit(1).exec(
function (err, obj) {
if (err) return console.log(err);
output.push(obj);
console.log('output LOG:' + output);
}
);
})(results, name);
}
// Now use the results array
console.log('OUTPUT:' results);
在&#39;输出LOG:&#39;我得到了应该的数组输出(为了简单起见,我没有在这里显示_id):
output LOG: {colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'}
output LOG: {colour: 'white', addedDate: '2014-09-24T23:00:00.000Z'}, {colour: 'red', addedDate: '2014-09-24T23:00:00.000Z'}
但是,最终输出仍为空。
OUTPUT:
如何填写“结果”&#39;阵列?事实上,我想把它传递给一个网页,所以我想在呈现页面之前提前收集这些颜色的所有结果。
答案 0 :(得分:0)
传递给exec
的函数可能与db
操作异步运行,在这种情况下,results
数组在您登录时不会被填充。< / p>
尝试:
setTimeout(function()
console.log('OUTPUT:' results);
}, 1000);
检查是否是这种情况,假设db事务占用最多1000毫秒。
注意:这是猜测,因为我从未使用过node / mongo。
答案 1 :(得分:0)
在本节中,
(function(output,colour_name){
/* Fetch documents here and send to client from here */
})(结果,名称);
变量&#39;结果&#39;,&#39; name&#39;传递给函数,由于范围问题,这些值不会在外部更新(即使它们在内部更改)。
您可以在获取文档后立即获取文档并将这些文档发送给客户端。
答案 2 :(得分:0)
Mongoose调用是异步的。发生了什么事情是您将每个Color.find
次调用添加到事件队列中,然后在任何console.log('OUTPUT:', results);
调用运行之前调用Color.find
。这意味着在那个时间点,你的数组是空的。
传递剩余通话次数和回拨次数。查询完每种颜色后,调用回调。这是fiddle
var colours = ['white', 'red'];
var result = {
items: [],
left: colours.length
};
function myCallback(param){
console.log(param);
}
for(var i=0; i<colours.length; ++i){
(function(results, colour_name, cb){
...
setTimeout(function(){ // remove this, just simulating an async call
// this should be inside the Color.find callback
result.items.push(colour_name);
result.left--;
if (!result.left) {
cb(result.items);
}
},0);
...
}(result, colours[i], myCallback ));
}