簡體   English   中英

javascript中循環結束后,如何執行語句?

[英]How can I execute a statement AFTER a loop finishes in 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)放入循環中,它將打印出三遍,這不是我想要的。 我只想要最后一個字符串(即...<br>...<br>...<br> 。我也最終不能返回temphtml字符串,這實際上很重要。這是javascript?為什么循環后不執行語句?

另外:有沒有更好的方法來按順序檢索存儲在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()使用Promise.all()返回“一個大結果”。 但是,您還需要從mongojs切換到mongojs promised-mongo ,作為最接近的等效項,因為實際上有更多的mongodb驅動程序支持promise。 那只是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,但根據我的閱讀,它是異步的。 因此,正在發生的是您的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一無所知,但它應該使您走上正確的道路。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM