javascript中的循环结束后,如何执行语句? [英] How can I execute a statement AFTER a loop finishes in javascript?

查看:1236
本文介绍了javascript中的循环结束后,如何执行语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查询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)放入循环中,它将打印出3次,这不是我想要的.我只想要最后一个字符串(即...<br>...<br>...<br>.而且我最终也无法返回temphtml字符串,这实际上很重要.这是javascript的怪癖吗?为什么循环后不执行语句? /p>

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

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

现在,游戏应该使用x和y值作为坐标在所有空白区域中显示".".数据库通过"x"值编制索引.

解决方案

请参见 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对象会延迟到实际调用解析为止,因此您可以在循环中提供参数,但稍后再执行. /p>

I'm querying a mongo database to retrieve the tiles for the display in rougelike game. This is the function I use:

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();

If I put the console.log(temphtml) inside the loop, it prints out three times which isn't what I want. I only want the final string (i.e. ...<br>...<br>...<br>. Also I can't ultimately return the temphtml string, which is actually the important thing. Is this some quirk of javascript? Why would it not execute statements after the loop?

Also: is there a better way to retrieve every element of a grid that's stored in a mongo database, in order, so it can be displayed properly? Here's what the mongo documents look like:

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

Right now, the game is supposed to display a "." in all empty spaces using the x and y values for the coordinates. The database is indexed by "x" values.

解决方案

See async.whilst. You want flow control of the for loop, for which this provides a callback to control each loop iteration.

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);
  }
)

Either that or use Promise.all() on collected promises to return "one big result". But you would also need to switch to promised-mongo from mongojs, as the nearest equivalent, since there are more mongodb drivers that actually support promises. That one is just the direct fork from 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("");
})

Not exactly the same thing, since it's one list output and not three, but the point is that the Promise objects defer until actually called to resolve, so you can feed the paramters in the loop, but execute later.

这篇关于javascript中的循环结束后,如何执行语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆