デバイスからファイル名のリストを取得し、ファイルを読み取ってリストを作成するルーチンがあります。ただし、呼び出しルーチンは常にゼロ項目で戻ります。ファイル名を印刷したので、それらが存在することはわかっていますが、ファイルを読み取る前に非同期が戻っているようです。 HTTP呼び出しを行うときに同様のコードを使用しました。しかし、ここで何かが原因で、ルーチンは完了していなくてもリストを返します。おそらく、私が間違った時間にそれを呼んでいる可能性がありますか?ここでretrieveItemsを呼び出しています:
@override
void initState() {
super.initState();
retrieveItems();
}
最終的には更新ボタンが表示されますが、今のところ、リストにファイルのデータを入力するだけです...
呼び出し先
Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
files.forEach((filename) async {
final file = await File(filename);
String contents = await file.readAsString();
User usr = User.fromJson(json.decode(contents));
String name = usr.NameLast + ", " + usr.NameFirst;
print(name);
l.add(name);
}
return l;
発信者
void retrieveItems() async {
LocalStorage storage = new LocalStorage();
await storage.readHeaderData().then((item) {
try {
if ((item != null ) &&(item.length >= 1)) {
setState(() {
users.clear();
_users.addAll(item);
});
} else {
setState(() {
_users.clear();
final snackbar = new SnackBar(
content: new Text('No users found.'),
);
scaffoldKey.currentState.showSnackBar(snackbar);
});
}
} on FileNotFoundException catch (e) {
print(e.toString()); //For debug only
setState(() {
_users.clear();
});
});
}
});
このコード
_Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
files.forEach((filename) async {
final file = await File(filename);
String contents = await file.readAsString();
User user = User.fromJson(json.decode(contents));
String name = user.NameLast + ", " + user.NameFirst;
print(name);
l.add(name);
}
return l;
}
_
リストl
を返し、asyc forEach(...)
コールバックを処理します
に変更した場合
_Future<List<String>> readHeaderData() async {
List<String> l = new List();
List<String> files = await readHeaders(); // Gets filenames
for(var filename in files) { /// <<<<==== changed line
final file = await File(filename);
String contents = await file.readAsString();
User user = User.fromJson(json.decode(contents));
String name = user.NameLast + ", " + user.NameFirst;
print(name);
l.add(name);
}
return l;
}
_
すべてのファイル名が処理されるまで、関数は戻りません。
_files.forEach((filename) async {
_
つまり、コールバック内でawait
を使用できますが、forEach
は_(filename) async {...}
_が何を返すかを気にしません。
list.map(f)
の使用に関するGünterのコメントを拡張するために、forEach
呼び出しを正しく機能するように変換する例を次に示します。
forEach
が先物を待つと誤って想定しています:
_Future<void> brokenExample(List<String> someInput) async {
List<String> results;
someInput.forEach((input) async {
String result = await doSomethingAsync(input);
results.add(result);
});
return results;
}
_
_Future.wait
_および.map()
を使用して、非同期関数が完了するのを待ちます。
_Future<void> correctedExample(List<String> someInput) async {
List<String> results;
await Future.wait(someInput.map((input) async {
String result = await doSomethingAsync(input);
results.add(result);
}));
return results;
}
_
また可能
await Future.forEach(yourList, (T elem) async { ...async staff });