Pourquoi Firebase perd-il la référence en dehors de la fonction once() ?
Firebase utilise un traitement asynchrone, ce qui signifie que la récupération des données de la base de données n'est pas exécutés séquentiellement. Par conséquent, tenter d'accéder à la liste d'utilisateurs immédiatement après avoir attaché un écouteur dans la fonction userService.getUsers ne donnera pas le résultat souhaité.
L'extrait de code fourni :
.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' } }]);
Démontre cela comportement asynchrone. La sortie de la console serait :
before attaching listener after attaching listener got value
Pour résoudre ce problème, vous disposez de trois options :
1. Utilisez la liste des utilisateurs dans le rappel :
Déplacez tout le code nécessaire qui opère sur la liste des utilisateurs dans le rappel :
ref.once('value', function(snapshot) { users = snapshot.val(); for(var key in users) { users[key].id = key; } console.log(users); // outputs all users })
2. Renvoyer une promesse :
Renvoyer une promesse de userService.getUsers et y enchaîner les opérations ultérieures :
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); }); }
Vous pouvez ensuite utiliser la promesse pour continuer le traitement une fois les données chargées :
userService.getUsers().then(function(userList) { console.log(userList); })
3. Utiliser Async et Await (nécessite la prise en charge d'ES2017) :
Marquez la fonction getUsers comme asynchrone et utilisez le mot-clé wait pour suspendre l'exécution jusqu'à ce que la promesse soit résolue :
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; }
Vous pouvez utilisez maintenant la fonction comme :
async function getAndLogUsers() { const userList = await userService.getUsers(); console.log(userList); }
En comprenant l'exécution asynchrone dans Firebase, vous pouvez accéder efficacement aux données de votre base de données et évitez les références potentielles non définies.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!