2017-02-20 10 views
1

У меня есть функция, которая получает массив объектов. Массив выглядит так:Как заставить For loop ждать ответа базы данных Firebase?

var receivedObjects = [{nuih329hs: 100}, {8suwhd73h: 500}, {2dsd73ud: 50}, {9u238ds: 200}]; 

Каждый ключ является идентификатором, а каждое значение является числом. Объекты находятся в заданном порядке, и то, что я хочу сделать, - это перебирать объекты и определять каждое значение как переменную, которое я буду использовать при создании строки html.

Проблема, с которой я столкнулась, заключается в том, что я должен сделать вызов базы данных Firebase внутри этого итерационного кода, результатом является то, что, хотя строка успешно создается для каждого значения объекта, значение, введенное в каждую строку, равно всегда одно и то же (последнее/последнее значение в массиве объектов), поэтому в приведенном выше случае число 200 появляется во всех четырех строках.

Я думаю, что это может произойти, потому что, возможно, все итерации завершаются до того, как первый вызов Firebase будет завершен, что означает, что переменная currentValue (которая я вхожу в строки) установлена ​​в последнем значении в массиве до первый вызов Firebase сделан.

Примечание: существует еще один массив (называемый listOfIds), который содержит идентификаторы Firebase, я могу успешно использовать каждый 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("The current ID is: "+currentID+" and the current value is: "+currentValue); внутри функции успешного вызова Firebase отображала правильный currentValue?

+1

Для получения другого примера возврата обещаний из функции см. Ответ, который я только что написал здесь: http://stackoverflow.com/questions/42346560/how-do-i-make-a-function-return- данных, что-было-множество-в-функции-ребенок-snapsho/42347920 # 42347920. –

+0

Спасибо @FrankvanPuffelen, что выглядит интересно, есть ли разница в производительности между двумя методами, или они оба будут равны? – Emily

+1

Доминирующим фактором для производительности будет количество данных, которые вы читаете/записываете. Если между ними одно и то же, любые другие различия, вероятно, будут несущественными. –

ответ

4

Вместо того, чтобы ожидание цикла, вы можете использовать функцию поставить 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) 
} 
+0

Это прекрасно, большое вам спасибо! – Emily