Javascript 如何使For循环等待Firebase数据库响应?

Javascript 如何使For循环等待Firebase数据库响应?,javascript,arrays,firebase,firebase-realtime-database,Javascript,Arrays,Firebase,Firebase Realtime Database,我有一个接收对象数组的函数。该数组如下所示: var receivedObjects = [{nuih329hs: 100}, {8suwhd73h: 500}, {2dsd73ud: 50}, {9u238ds: 200}]; 每个键都是一个ID,每个值都是一个数字。 对象是按设定顺序排列的,我要做的是遍历对象,并将每个值定义为变量,然后在创建html行时使用变量 我遇到的问题是,我必须在这个迭代代码中调用Firebase数据库,结果是,当为每个对象值成功创建一行时,输入到每行的值始终与对象

我有一个接收对象数组的函数。该数组如下所示:

var receivedObjects = [{nuih329hs: 100}, {8suwhd73h: 500}, {2dsd73ud: 50}, {9u238ds: 200}];
每个键都是一个ID,每个值都是一个数字。 对象是按设定顺序排列的,我要做的是遍历对象,并将每个值定义为变量,然后在创建html行时使用变量

我遇到的问题是,我必须在这个迭代代码中调用Firebase数据库,结果是,当为每个对象值成功创建一行时,输入到每行的值始终与对象数组中的最后/最近值相同,因此,在上述情况下,数字200出现在所有四行中

我认为这可能是因为所有的迭代都是在第一次Firebase调用完成之前完成的,这意味着我在行中输入的变量currentValue被设置为第一次Firebase调用之前数组中的最后一个值

注意:还有另一个名为listOfIds的数组,它包含Firebase ID,我能够成功地将此数组中的每个ID用作Firebase调用中使用的变量,var currentID就是该变量

这就是功能:

function populateTable(receivedObjects){

   var receivedObjectsLength = receivedObjects.length;
   // Note: an object array called listOfIds exists here (containing Firebase IDs to be used for querying Firebase), it's referenced below.

   for (var i = 0; i < receivedObjectsLength; i++) {

      // listOfIds is an Object array 
      var currentID = Object.keys(listOfIds[i]);

      var term = (Object.keys(receivedObjects[i])[0]);
      var currentValue = receivedObjects[i][term];

      //The following line is showing the correct ID and Value for each iteration:
      console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);

      firebase.database().ref('/users/' + currentID).once('value').then(function(child) {

      // This is where the rows are created, ``currentValue`` is used here, but it's appearing as the same value in every row.

      // The next line is showing the correct current ID, but it's showing the currentValue as "200" in every row.
      console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);

    });
  }
}

我很困惑,因为我以为Javascript迭代代码会等到Firebase调用返回数据,但事实似乎并非如此?如何更改代码,使console.log行当前ID为:+currentID+,当前值为:+currentValue;在Firebase调用成功函数内部,将显示正确的currentValue?

而不是让循环等待,您可以使用一个函数将currentID和currentValue放入它们自己的作用域中,以便它们不会在每次迭代中被覆盖:

function getUser(currentID, currentValue) {
    return firebase.database().ref('/users/' + currentID).once('value').then(function(child) {
        console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);
    });
}
在您的循环中:

for (var i = 0; i < receivedObjectsLength; i++) {
    ...
    getUser(currentID, currentValue)
}

您可以使用函数将currentID和currentValue放入各自的作用域,而不是让循环等待,这样它们就不会在每次迭代中被覆盖:

function getUser(currentID, currentValue) {
    return firebase.database().ref('/users/' + currentID).once('value').then(function(child) {
        console.log("The current ID is: "+currentID+" and the current value is: "+currentValue);
    });
}
在您的循环中:

for (var i = 0; i < receivedObjectsLength; i++) {
    ...
    getUser(currentID, currentValue)
}

关于从函数中返回承诺的另一个例子,请参见我刚才在这里写的答案:。Thank@FrankvanPuffelen,这看起来很有趣,这两种方法之间是否存在性能差异,或者它们是否都大致相同?性能的主要因素将是您读/写的数据量。如果它们之间是相同的,那么任何其他差异都可能无关紧要。有关从函数中返回承诺的另一个示例,请参见我刚才在这里写的答案:。Thank@FrankvanPuffelen,看起来很有趣,这两种方法之间是否存在性能差异,或者两者大致相等?性能的主要因素是您读/写的数据量。如果它们之间是相同的,那么任何其他的差异都可能是无关紧要的。它起作用了,但我想知道在异步中这是一种正确的方式吗?它起作用了,但我想知道在异步中这是一种正确的方式吗??