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 会在静态分析期间发现此问题。
如何让 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 theloadFeed()
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 会在静态分析期间发现此问题。