flutter 我的异步调用在forEach循环中填充list之前返回

ldfqzlk8  于 2023-08-07  发布在  Flutter
关注(0)|答案(6)|浏览(161)

我有一个例程,它从设备中获取一个文件名列表,然后读取文件以构建一个列表。但是,调用例程总是返回零项。我打印文件名,所以我知道它们存在,然而,在我读取文件之前,异步似乎正在返回。我在进行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();
        });
      });
    }
  });

nwlqm0z1

nwlqm0z11#

这个代码

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 {...}返回什么。

rhfm7lfc

rhfm7lfc2#

也有可能

await Future.forEach(yourList, (T elem) async { ...async staff });

字符串

tuwxkamq

tuwxkamq3#

为了扩展Günter关于使用list.map(f)的评论,这里有一个转换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;
}

2eafrhcq

2eafrhcq4#

我遇到了类似的问题。问题是, dart 不会等待“每一个”相反,公众相信。有两种解决方案:

1) Convert forEach to for loop as indicated by others. Another is use Future:
2) await Future.forEach(list, (item) async {
   // your code
    final result = await getMyResult();
   });

字符串

rsl1atfo

rsl1atfo5#

另一个选择

Future.wait(someList.map((item) => something_returns_future(item)));

字符串

qcbq4gxm

qcbq4gxm6#

Future.forEach()将按顺序执行future。迭代等待直到future完成,然后继续下一个元素。
Future.wait()将并行执行futures。返回一个future,它将在所有提供的future完成后完成。
参见Future class

相关问题