我怎样才能执行一个语句后,一个循环在JavaScript完成?

我正在查询一个mongo数据库,以便在类似rouge的游戏中检索显示的图块。 这是我使用的function:

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)放在循环中,它会打印出三次,这不是我想要的。 我只想要最后一个string(即...<br>...<br>...<br>我也不能最终返回temphtmlstring,这实际上是重要的事情。这是一些怪癖javascript?为什么不在循环之后执行语句?

另外:有没有更好的方法来检索存储在mongo数据库中的网格的每个元素,以便它可以正确显示? 这是mongo文档的样子:

 { "_id": {"$oid": "570a8ab0e4b050965a586957"}, "x": 0, "y": 0, "display": "." } 

现在,游戏应该使用坐标的x和y值在所有空白处显示“ . ”。 数据库按“x”值进行索引。

请参阅async.whilst 。 你需要stream控制的for循环,为此提供了一个callback来控制每个循环迭代。

 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()收集到的promise来返回“一个大的结果”。 但是你也需要从mongojs切换到promised-mongo ,因为有更多的mongodb驱动程序支持诺言。 那只是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对象延迟,直到实际调用解决,所以你可以提供参数在循环中,但稍后执行。

我不使用MongoDB,但从我读的是asynchronous的。 那么,发生了什么事是你的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一无所知,但它应该把你放在正确的道路上。