【问题标题】:Flutter Async Load Multiple Functions One After The OtherFlutter 异步加载多个函数一个接一个
【发布时间】:2021-06-30 15:20:45
【问题描述】:

我怎样才能让 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;
}

【问题讨论】:

    标签: flutter dart asynchronous flutter-future


    【解决方案1】:

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

    “WhenComplete”,注册一个函数,当这个future完成时调用。

    [action] 函数在这个 future 完成时被调用,无论是 使用值或错误来执行此操作。

    这是“finally”块的异步等价物。

    • load改成future函数,加上返回值让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')));}
      

    【讨论】:

    • 如果您已经在使用await,则无需使用.whenComplete()
    【解决方案2】:

    似乎load() 函数本身在loadFeed() Future 完成之前完成,我该如何解决这个问题?

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

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

    你的load函数调用loadFeed,注册一个Future.then回调,忽略新返回的Future,注册回调后同步返回给调用者。它不使用await 等待Future 完成,也不将Future 返回给调用者以允许调用者等待Future

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-22
      • 2019-05-22
      • 2020-09-17
      • 2021-04-30
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多