私のデータは次のようなものです:
{
"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"
}
}
次の関数を使用しています。
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
として)アクセスしますFuture
のインスタンスである値を持つマップを返すので、それらから実際の値を抽出したいと思います。このため、マップ上でforEach
が呼び出されます。ただし、値として取得できるのはFutureのインスタンスのみです。実際の値を取得するにはどうすればよいですか?
非同期実行から同期実行に戻す方法はありません。
Future
から値を取得するには、2つの方法があります
コールバックをthen(...)
に渡します
theFuture.then((val) {
print(val);
});
または、async
/await
を使用して構文を改善します
Future foo() async {
var val = await theFuture;
print(val);
}
await value
式が完了するのを待っていません。
forEach
呼び出しはマップエントリを実行し、それぞれの非同期計算を開始します。 forEach
は関数の戻り値を使用しないため、その計算の将来は破棄されます。次に、非同期計算が完了する前にマップを返すため、マップの値は先物です。最終的には将来のものに変更されますが、いつ完了したかはわかりません。
forEach
呼び出しの代わりに、以下を試してください。
await Future.wait(groupMapWithDetails.keys.map((key) async {
groupMapWithDetails[key] = await groupMapWithDetails[key];
});
これにより、マップ内の各キーに対して非同期操作が実行され、すべてのキーが完了するまで待機します。その後、マップは将来の値ではないはずです。