Flutter Async 一个接一个地加载多个函数

Flutter Async Load Multiple Functions One After The Other

如何让 Flutter 知道等待一个函数(以及未来)完成,直到调用下一个函数? load() 函数本身似乎在 loadFeed() Future 完成之前完成,我该如何解决?

这是我当前的代码:

ValueNotifier<List> data = ValueNotifier([]);
ValueNotifier<bool> loading = ValueNotifier(true);

loadAll() async {
  await load(0, 'url1');
  print("0 finished");
  await load(1, 'url2');
  print("1 finished");
  await load(2, 'url3');
  print("2 finished");
}

load(int categoryIndex, String _url) async {
  loadFeed(_url).then((result) {
    if (null == result || result.toString().isEmpty) {
      print("error");
      return;
    }
    data.value = [[],[],[],];
    for (var i = 0; i < result.items.length; i++) {
      data.value[categoryIndex].add(result.items[i]);
    }
    data.notifyListeners();
  });
}

Future<RssFeed> loadFeed(String _url) async {
  loading.value = true;
  try {
    final client = http.Client();
    final response = await client.get(Uri.parse(_url));

    return RssFeed.parse(response.body);
  } catch (e) {
    print("error");
  } finally {
    loading.value = false;
  }
  return null;
}

在未来的功能中,您可以使用 whencomplete,来自文档:

"WhenComplete", Registers a function to be called when this future completes.

The [action] function is called when this future completes, whether it does so with a value or with an error.

This is the asynchronous equivalent of a "finally" block.

  • load改成未来的函数,并添加一个return值让dart知道你完成了,像这样:

    Future load(int categoryIndex, String _url) async {
       loadFeed(_url).then((result) {
         if (null == result || result.toString().isEmpty) {
           print("error");
           return;
         }
         data.value = [[],[],[],];
         for (var i = 0; i < result.items.length; i++) {
           data.value[categoryIndex].add(result.items[i]);
         }
        return data.notifyListeners(); //add a return here, to tell dart that this function is done.
       });
     }
    
  • 把你的loadAll改成这样:

    loadAll() async { 
    await load(0, 'url1')
    .whenComplete(() async => await load(1, 'url2')
    .whenComplete(() async => await load(2, 'url3')));}
    

It seems like the load() function itself completes before the loadFeed() Future is finished, how can I fix that?

这正是问题所在。你这样做:


load(int categoryIndex, String _url) async {
  loadFeed(_url).then((result) {
    // ... bunch of code...
  });
}

您的 load 函数调用 loadFeed,注册一个 Future.then 回调,忽略新 returned Future,并同步 return s 回调注册后的调用者。它不使用await等待Future完成,也不returnFuture给调用者让调用者等待Future.

如果你使用 async/await 而不是将其与原始 Future 混合使用会简单得多 API:

Future<void> load(int categoryIndex, String _url) async {
  var result = await loadFeed(_url);
  // ... bunch of code...
}

此外,启用 unawaited_futures lint in your analysis_options.yaml file 会在静态分析期间发现此问题。