Flutter 异步加载多个函数一个接一个
Posted
技术标签:
【中文标题】Flutter 异步加载多个函数一个接一个【英文标题】:Flutter Async Load Multiple Functions One After The Other 【发布时间】: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;
【问题讨论】:
【参考方案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 会在静态分析期间发现此问题。
【讨论】:
以上是关于Flutter 异步加载多个函数一个接一个的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 专题15 图解 ListView 异步加载数据与等待 #yyds干货盘点#