我的异步调用在 forEach 循环中填充列表之前返回 [英] My async call is returning before list is populated in forEach loop

查看:20
本文介绍了我的异步调用在 forEach 循环中填充列表之前返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个例程,它从设备获取文件名列表,然后读取文件以构建列表.但是,调用例程总是返回零项.我打印了文件名,所以我知道它们存在,但是,在我读取文件之前,异步似乎正在返回.我在进行 HTTP 调用时使用了类似的代码.但是,这里的某些事情导致例程即使尚未完成也返回列表.也许,有可能我在错误的时间调用它?我在这里调用retrieveItems:

I have a routine which gets a list of filenames from the device, then reads the file(s) to build a list. However, the calling routine always returns with zero items. I print the filenames, so I know they exist, however, it appears that the async is returning before I read the files. I used similar code when making an HTTP call. But, something here is causing the routine to return the list even though it hasn't completed. Perhaps, it is possible that I am calling it at the wrong time? I am calling retrieveItems here:

@override
  void initState() {
    super.initState();
    retrieveItems();
  }

最终我会有一个刷新按钮,但现在我只想用文件中的数据填充列表...

Eventually I will have a refresh button, but for now I'd simply like the list to populate with the data from the files...

被叫方

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,然后处理异步forEach(...)回调

returns the list l and then processes the asyc forEach(...) callbacks

如果你改成

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;
}

在处理完所有文件名之前,该函数不会返回.

the function will not return before all filenames are processed.

files.forEach((filename) async {

意味着你可以在回调中使用 await,但是 forEach 并不关心什么 (filename) async {...} 返回.

means that you can use await inside the callback, but forEach doesn't care about what (filename) async {...} returns.

这篇关于我的异步调用在 forEach 循环中填充列表之前返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆