Firebaseからデータを非同期的に読み取るのが問題です(imjaredという)。したがって、コードはあなたが思う順序で実行されません。
.service('userService', [function() {
this.getUsers = function() {
var ref = firebase.database().ref('/users/');
console.log("before attaching listener");
ref.once('value').then(function(snapshot) {
console.log("got value");
});
console.log("after attaching listener");
}
}]);
はこれの出力は次のようになります:
が得たリスナー取り付けた後、リスナー
を取り付ける前に、それはちょうど少数のログステートメントでそれを簡略化することにより、それを見るのが一番簡単です値
注文を知るリスナーを取り付けた直後にユーザーリストを印刷できない理由を完全に説明する必要があります。解決のための今すぐHow do I return the response from an asynchronous call?
:いない場合は、私はこの偉大な答えを読んでも、お勧めしますがいずれかは、コールバックにユーザリストを使用する必要があるか約束を返します。コールバックにユーザリストを必要とするすべてのコードを移動:
これは非同期コードに対処する最古の方法でコールバックで
をユーザリストを使用してください。
ref.once('value', function(snapshot) {
users = snapshot.val();
for(var key in users) {
users[key].id = key;
}
console.log(users); // outputs all users
})
あなたは、「ユーザリストがロードされるたびに、その内容を印刷する」「その内容を印刷し、最初のロードユーザーリスト」から、あなたのコードをリフレーミングしています。定義の違いは軽微ですが、突然あなたは完全に非同期の読み込みに対処できます。
あなたのコードで行うようにあなたはまた、約束と同じ操作を行うことができます。
ref.once('value').then(function(snapshot) {
users = snapshot.val();
for(var key in users) {
users[key].id = key;
// do some other stuff
}
console.log(users); // outputs all users
});
しかし、約束を使用して、直接、コールバックを使用しての上で1つの巨大な利点があります:あなたが約束を返すことができます。
戻る約束
多くの場合、あなたはgetUsers()
機能にユーザーを必要とするすべてのコードを配置するとは思わないだろう。その場合、あなたはどちらかは(私はここでは表示されませんこれは、それはあなたがonce()
に渡すことができますコールバックと非常に似ています)getUsers()
にコールバックを渡すことができますまたはあなたはgetUsers()
から約束を返すことができます。
this.getUsers = function() {
var ref = firebase.database().ref('/users/');
return ref.once('value').then(function(snapshot) {
users = snapshot.val();
for(var key in users) {
users[key].id = key;
// do some other stuff
}
return(users);
}).catch(function(error){
alert('error: ' + error);
});
}
このサービスで
、我々は今getUsers()
を呼び出し、それらがロードされていたら、ユーザーを取得するために結果の約束を使用することができます。
userService.getUsers().then(function(userList) {
console.log(userList);
})
をということで、あなたは非同期の獣を飼いならしています。まあ、今は少なくとも。これは、熟練したJavaScript開発者でさえもしばらくの間混乱させてしまうので、慣れるまでに時間がかかっても心配しないでください。
私の非同期関数が正常に完了した後に 'userList'をポピュレートするためのロジックを追加しました –
' setTimeout() 'がうまく動作しないかもしれません(ほとんどの場合ネットワーク遅延に依存します)しかし、この問題の解決策は決して**まったくありません。正しい解決策は、 'users'リストを必要とするコードをコールバック/ブロックに移動することです。 –