如何解决Flutter 异步加载多个函数一个接一个
如何让 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;
}
解决方法
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...
}
此外,在您的 unawaited_futures
lint 中启用 analysis_options.yaml
file 会在静态分析期间发现此问题。
在以后的函数中,您可以使用文档中的 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')));}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。