我有一个游戏网格,我正试图融入一行数组,每一行都有许多块。这些块存储在同一个集合中,并且具有行和列字段。
我当前的尝试如下。
exports.findById = function(req,res) {
var id = req.params.id;
console.log('Retrieving game #' + id);
db.games.findOne( { "_id" : ObjectId(id) }, function(err, game_obj) {
if(err || !game_obj) {
console.log("no game");
res.send({'error':'An error has occurred'});
} else {
var rows = [];
function getRowBlocks(err,blocks) {
if(err || !blocks) {
console.log("no blocks");
res.send({'error':'An error has occurred'});
} else {
console.log(blocks[0].row + " has " + blocks.length + " blocks");
rows[blocks[0].row] = blocks;
}
}
for(i=0;i<game_obj.farthest_row;i++) {
db.blocks.find( { "game_id" : ObjectId(id), "row" : i }).sort( { "column" : 1 }).toArray(getRowBlocks);
}
res.send('game', { row_list : rows, game : game_obj});
}
});
}
但是由于mongodb查找操作的范围为每一行调用,我实际上不能得到存储在rows
变量中的块。因为有多个操作运行,我不能简单地把res.send...
放在toArray
回调中。
我只能使用一个查询并在回调中构建数组,然后传递它,但我认为考虑到多个查询是异步发生的,并且可能有大量的行,这将是效率低得多。
我想我可以这样做,如果我可以传递行数组到查询回调,但我还没有能够找出如果这是可能的。
这就是async。Parallel用于:
// build a list of query-functions
var queries = [];
for (var i = 0; i < game_obj.farthest_row ; i++) {
queries.push(function(i, cb) {
db.blocks
.find( { "game_id" : ObjectId(id), "row" : i })
.sort( { "column" : 1 })
.toArray(cb);
}.bind(this, i)); // create a partial function to create a newly scoped 'i'
}
// pass the query functions to async, which will run them in parallel,
// gather all the results, and finally call the callback function with
// the results-array
async.parallel(queries, function(err, results) {
if (err)
// handle error
// results now contains the query results (array-in-array)
results.forEach(function(blocks) {
getRowBlocks(null, blocks); // this probably requires a rewrite...
});
});