我正在查询mongo数据库,以便在胭脂游戏中检索显示的图块。这是我使用的功能:
function get_display(){
var collections = ['austinsroom'];
var db = mongojs(uri, collections);
var temphtml = '';
for(var j = 0; j < 3; j++) {
console.log("y=" + String(j));
db.austinsroom.find({"y": j}, {}).sort({"x": 1}, function(err, records) {
if(err) {
console.log("There was an error executing the database query.");
return;
}
var i = records.length;
while(i--) {
temphtml += records[i].display;
}
temphtml += '<br>';
//console.log(temphtml);
//return temphtml;
//THE ONLY WAY I CAN GET ANYTHING TO PRINT IN THE CONSOLE IS IF I PUT IT INSIDE THE LOOP HERE
});
//console.log(temphtml);
//return temphtml;
//THIS DOES NOTHING
}
//console.log(temphtml);
//return temphtml;
//THIS DOES NOTHING
}
get_display();
如果我把console.log(temphtml)
放在循环中,它会打印三次,这不是我想要的。我只想要最后一个字符串(即...<br>...<br>...<br>
。我也不能最终返回temphtml
字符串,这实际上是重要的事情。这是javascript的一些怪癖吗?为什么它不会在执行之后执行语句循环?
另外:有没有更好的方法来检索存储在mongo数据库中的网格的每个元素,以便它可以正确显示?这是mongo文档的样子:
{
"_id": {"$oid": "570a8ab0e4b050965a586957"},
"x": 0,
"y": 0,
"display": "."
}
现在,游戏应该使用坐标的x和y值在所有空白区域显示“.
”。数据库由“x”值索引。
答案 0 :(得分:5)
见async.whilst
。您需要for
循环的流控制,为此提供回调来控制每个循环迭代。
var temphtml = "",
j = 0;
async.whilst(
function() { return j < 3 },
function(callback) {
db.austinsroom.find({"y": j }, {}).sort({"x": 1}, function(err, records)
temphtml += records.map(function(el) {
return el.display;
}).join("") + '<br>';
j++;
callback(err);
});
},
function(err) {
if (err) throw err;
console.log(temphtml);
}
)
或者使用Promise.all()
收集的承诺返回“一个大的结果”。但是你还需要从mongojs
切换到promised-mongo
,作为最接近的等价物,因为有更多的mongodb驱动程序实际上支持promises。那个只是来自mongojs
的直接分支:
var temphtml = "",
j = 0,
promises = [];
for ( var j=0; j < 3; j++ ) {
promises.push(db.austinsroom.find({"y": j }, {}).sort({"x": 1}).toArray());
promises.push('<br>'); // this will just join in the output
)
Promise.all(promises).then(function(records) {
temphtml += records.map(function(el) {
return el.display;
}).join("");
})
不完全相同,因为它是一个列表输出而不是三个,但重点是Promise
个对象延迟直到实际调用解析,因此您可以在循环中提供参数,但稍后执行
答案 1 :(得分:0)
我不使用MongoDB,但从我正在阅读的内容中它是异步的。所以发生的事情是你的db.austinsroom.find
调用触发另一个“线程”并返回for循环以继续下一次迭代。
执行所需操作的一种方法是检查db.austinsroom.find
函数的末尾,看看是否已完成for循环。类似的东西:
function get_display()
{
var collections = ['austinsroom'];
var db = mongojs(uri, collections);
var temphtml = '';
var doneCounter = 0;
for(var j = 0; j < 3; j++)
{
console.log("y = " + String(j));
db.austinsroom.find({"y": j}, {}).sort({"x": 1}, function(err, records)
{
if(err)
{
console.log("There was an error executing the database query.");
return;
}
var i = records.length;
while(i--)
{
temphtml += records[i].display;
}
temphtml += '<br>';
// we're done with this find so add to the done counter
doneCounter++;
// at the end, check if the for loop is done
if(doneCounter == 3)
{
// done with all three DB calls
console.log(temphtml);
}
});
}
}
这可能不是最好的方式,因为我对MongoDB一无所知,但它应该让你走上正确的道路。