Firebase は、once() 関数の外で参照を失うのはなぜですか?
Firebase は非同期処理を利用します。つまり、データベースからのデータの取得は非同期処理ではありません。順次実行されます。その結果、userService.getUsers 関数でリスナーをアタッチした直後にユーザー リストにアクセスしようとすると、目的の出力が得られません。
提供されるコード スニペットは、
.service('userService', [function() { this.getUsers = function() { var users; var userList; var ref = firebase.database().ref('/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 }).then(function(){ userList = users; console.log(userList); // outputs all users },(function(error){ alert('error: ' + error); }); console.log(userList); // outputs 'undefined' } }]);
これを示しています。非同期動作。コンソール出力は次のようになります:
before attaching listener after attaching listener got value
この問題を解決するには、次の 3 つのオプションがあります:
1。コールバックでユーザー リストを使用します:
ユーザー リストを操作する必要なコードをすべてコールバックに移動します:
ref.once('value', function(snapshot) { users = snapshot.val(); for(var key in users) { users[key].id = key; } console.log(users); // outputs all users })
2. Promise を返す:
userService.getUsers から Promise を返し、後続の操作をそれにチェーンします:
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); }); }
データがロードされたら、Promise を使用して処理を続行できます。 :
userService.getUsers().then(function(userList) { console.log(userList); })
3. Async と Await を使用する (ES2017 サポートが必要):
getUsers 関数を非同期としてマークし、await キーワードを使用して Promise が解決されるまで実行を一時停止します:
this.getUsers = async function() { var ref = firebase.database().ref('/users/'); const snapshot = await ref.once('value'); const users = snapshot.val(); for(var key in users) { users[key].id = key; // do some other stuff } return users; }
次のような関数を使用します。
async function getAndLogUsers() { const userList = await userService.getUsers(); console.log(userList); }
Firebase での非同期実行を理解することで、データベースのデータに効果的にアクセスし、未定義の参照の可能性を回避できます。
以上がFirebase 参照が「once()」関数の外で未定義になるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。