2017-02-20 5 views
1

私はオブジェクト配列を受け取る関数を持っています。配列は次のようになります。FirebaseデータベースレスポンスのForループ待機を行うには?

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

各キーはIDであり、各値は数値です。 オブジェクトは設定された順序にあり、オブジェクトを繰り返し処理し、各値を変数として定義します。次に、html行を作成するときに使用します。

私が抱えている問題は、この繰り返しコード内でFirebaseデータベースを呼び出す必要があります。その結果、各オブジェクト値に対して行が正常に作成されている間に、各行に入力された値が常に同じ(オブジェクト配列内の最後の/最新の値)ので、上記の場合、数字200が4行すべてに表示されます。

最初のFirebase呼び出しが完了する前にすべての反復が完了している可能性があります。これは変数currentValue(行に入力しています)が配列の最後の値に設定されていることを意味します最初のFirebase呼び出しが行われます。

注:Firebase IDを含む別の配列(listOfIds)があります。Firebase呼び出しで使用する変数としてこの配列の各IDを正常に使用できます。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); 

    }); 
    } 
} 

私は、データがFirebase呼び出しから返されるまで、Javascriptの反復コードが待つだろうと思ったが、これが当てはまらないようですので、私は、非常に混乱しています? Firebaseのコール成功関数内のconsole.log("The current ID is: "+currentID+" and the current value is: "+currentValue);行に正しい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); 
    }); 
} 

+1

関数から約束を返す別の例については、ここで書いた答えを参照してください。http://stackoverflow.com/questions/42346560/how-do-i-make-a-function-return-データ内で設定された機能の子スナップショット/ 42347920#42347920 –

+0

ありがとう@FrankvanPuffelen、面白そうに見えますが、2つの方法のパフォーマンスに違いがありますか、どちらもほぼ同じですか? – Emily

+1

パフォーマンスの主な要因は、読み書きするデータの量です。それが同じであれば、他の相違は重要ではないようです。 –

答えて

4

代わりにループ待機させるの彼らは反復ごとに上書きされないように、あなたは自分のスコープにcurrentIDcurrentValueを入れて機能を使用することができます

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

これは完璧です、ありがとうございます! – Emily

関連する問題