Mes données ressemblent à ceci:
{
"five": {
"group": {
"one": {
"order": 2
},
"six": {
"order": 1
}
},
"name": "Filbert",
"skill": "databases"
},
"four": {
"group": {
"three": {
"order": 2
},
"two": {
"order": 1
}
},
"name": "Robert",
"skill": "big data"
},
"one": {
"name": "Bert",
"skill": "data analysis"
},
"seven": {
"name": "Colbert",
"skill": "data fudging"
},
"six": {
"name": "Ebert",
"skill": "data loss"
},
"three": {
"name": "Gilbert",
"skill": "small data"
},
"two": {
"name": "Albert",
"skill": "non data"
}
}
J'utilise la fonction suivante:
Future retrieve(String id) async {
Map employeeMap = await employeeById(id); //#1
if (employeeMap.containsKey("group")) { //#2
Map groupMap = employeeMap["group"];
Map groupMapWithDetails = groupMembersWithDetails(groupMap); #3
// above returns a Mamp with keys as expected but values
// are Future instances.
// To extract values, the following function is
// used with forEach on the map
futureToVal(key, value) async { // #4
groupMapWithDetails[key] = await value;
}
groupMapWithDetails.forEach(futureToVal); // #4
}
return groupMapWithDetails;
}
Map
) à partir de la base de données (Firebase)Future
, je veux en extraire les valeurs réelles. Pour cela, un forEach
est appelé sur la carte. Cependant, je ne reçois que des instances de Future en tant que valeurs.Comment puis-je obtenir les valeurs réelles?
Il n'y a aucun moyen de revenir de l'exécution asynchrone à l'exécution synchronisée.
Pour obtenir une valeur à partir d'un Future
, il existe deux façons
passer un rappel à then(...)
theFuture.then((val) {
print(val);
});
ou utilisez async
/await
pour une syntaxe plus agréable
Future foo() async {
var val = await theFuture;
print(val);
}
Vous n'attendez pas le await value
expressions à compléter.
L'appel forEach
parcourt les entrées de mappage et démarre un calcul asynchrone pour chacune. L'avenir de ce calcul est alors abandonné car forEach
n'utilise pas la valeur de retour de sa fonction. Ensuite, vous retournez la carte, bien avant la fin des calculs asynchrones, de sorte que les valeurs de la carte sont toujours des futurs. Ils finiront par devenir non-futurs, mais vous ne saurez pas quand cela sera fait.
Au lieu de l'appel forEach
, essayez:
await Future.wait(groupMapWithDetails.keys.map((key) async {
groupMapWithDetails[key] = await groupMapWithDetails[key];
});
Cela effectue une opération asynchrone pour chaque clé de la carte et attend que toutes se terminent. Après cela, la carte devrait avoir des valeurs non futures.