现在我有了这个脚本
Future<List<HotProducts>> _loadHotProducts;
Future<List<NewProducts>> _loadNewProducts;
Future<List<Promotion>> _loadPromotions;
Future<List<LatestSoldItem>> _loadLatestSoldItem;
setState(() {
userId = result;
_loadHotProducts = HotProductsApiClient().fetchHotProducts(http.Client(), userId);
_loadNewProducts = NewProductApiClient().fetchNewProducts(http.Client(), userId);
_loadPromotions = PromotionApiClient().fetchPromotion(http.Client());
_loadLatestSoldItem = LatestSoldApiClient().fetchProducts(http.Client(), userId);
});
我上面的所有脚本都是关于从服务器调用数据的。现在,我要一一运行。所以,我正在尝试这种方式
_loadHotProducts = HotProductsApiClient().fetchHotProducts(http.Client(), userId).then((_){
_loadNewProducts = NewProductApiClient().fetchNewProducts(http.Client(), userId);
});
我收到此错误
The getter 'length' was called on null.
Receiver: null
Tried calling: length
我该如何解决?还是有更好的方法?
答案 0 :(得分:1)
await
用于中断过程流,直到async
方法完成为止。
then
不会中断处理流程(意味着将执行下一条指令),但是使您可以在async
方法完成后运行代码。
在您的示例中,使用then
时您无法实现所需的目标,因为代码没有正在等待,并且return语句已处理,因此返回空的List
添加await
时,您明确地说:在我的Future
完成之前不要走。
_loadHotProducts = await HotProductsApiClient().fetchHotProducts(http.Client(), userId);
_loadNewProducts = await NewProductApiClient().fetchNewProducts(http.Client(), userId);
_loadPromotions = await PromotionApiClient().fetchPromotion(http.Client());
_loadLatestSoldItem = await LatestSoldApiClient().fetchProducts(http.Client(), userId);
直接在await
中使用setState
不起作用,因为setState
功能不是async
,因此不建议使用。只需将它们包装在async
方法中将被调用的setState
函数中即可。所以最终结果应该是这样的:
Future<List<HotProducts>> _loadHotProducts;
Future<List<NewProducts>> _loadNewProducts;
Future<List<Promotion>> _loadPromotions;
Future<List<LatestSoldItem>> _loadLatestSoldItem;
Future load() async {
userId = result;
_loadHotProducts = await HotProductsApiClient().fetchHotProducts(http.Client(), userId);
_loadNewProducts = await NewProductApiClient().fetchNewProducts(http.Client(), userId);
_loadPromotions = await PromotionApiClient().fetchPromotion(http.Client());
_loadLatestSoldItem = await LatestSoldApiClient().fetchProducts(http.Client(), userId);
}
setState(() {
load();
});
答案 1 :(得分:1)
您遇到的问题在提取函数内部
您必须await
和所有http
和future
工作
您可以在DartPad中复制粘贴运行正确的代码和问题代码
以下演示具有3层函数调用,您可以在有无await
的情况下检查效果
如有疑问,只需打印消息,您就会看到执行顺序
如下提供了以下正确和问题
正确的完整代码
import 'dart:async';
import 'dart:math';
Future<String> fetchHotProductsLongJob() async {
await Future.delayed(const Duration(seconds: 10), () {
print('fetchHotProductsLongJob then');
});
print("fetchHotProductsLongJob done");
return "abc";
}
Future<String> fetchHotProducts() async {
await Future.delayed(const Duration(seconds: 7), () {
print("fetchHotProducts then");
});
await fetchHotProductsLongJob();
print("fetchHotProducts done");
return "abc";
}
Future<String> fetchNewProductsLongJob() async {
await Future.delayed(const Duration(seconds: 10), () {
print('fetchNewProductsLongJob then');
});
print("fetchNewProductsLongJob done");
return "abc";
}
Future<String> fetchNewProducts() async {
await Future.delayed(const Duration(seconds: 3), () async{
print("fetchNewProducts then");
await fetchNewProductsLongJob();
});
print("fetchNewProducts done");
return "abc";
}
void main() async{
print("fetchHotProducts job start");
var Job1 = await fetchHotProducts();
print("fetchHotProducts job done");
print("fetchNewProducts job start");
var Job2 = await fetchNewProducts();
print("fetchNewProducts job done");
}
正确的输出
fetchHotProducts job start
fetchHotProducts then
fetchHotProductsLongJob then
fetchHotProductsLongJob done
fetchHotProducts done
fetchHotProducts job done
fetchNewProducts job start
fetchNewProducts then
fetchNewProductsLongJob then
fetchNewProductsLongJob done
fetchNewProducts done
fetchNewProducts job done
删除一些等待后的问题代码
import 'dart:async';
import 'dart:math';
Future<String> fetchHotProductsLongJob() async {
Future.delayed(const Duration(seconds: 10), () {
print('fetchHotProductsLongJob then');
});
print("fetchHotProductsLongJob done");
return "abc";
}
Future<String> fetchHotProducts() async {
Future.delayed(const Duration(seconds: 7), () {
print("fetchHotProducts then");
});
fetchHotProductsLongJob();
print("fetchHotProducts done");
return "abc";
}
Future<String> fetchNewProductsLongJob() async {
await Future.delayed(const Duration(seconds: 10), () {
print('fetchNewProductsLongJob then');
});
print("fetchNewProductsLongJob done");
return "abc";
}
Future<String> fetchNewProducts() async {
await Future.delayed(const Duration(seconds: 3), () async{
print("fetchNewProducts then");
await fetchNewProductsLongJob();
});
print("fetchNewProducts done");
return "abc";
}
void main() async{
print("fetchHotProducts job start");
var Job1 = await fetchHotProducts();
print("fetchHotProducts job done");
print("fetchNewProducts job start");
var Job2 = await fetchNewProducts();
print("fetchNewProducts job done");
}
问题代码输出
您可以看到fetchHotProducts作业仍未完成
fetchHotProducts job start
fetchHotProductsLongJob done
fetchHotProducts done
fetchHotProducts job done
fetchNewProducts job start
fetchNewProducts then
fetchHotProducts then
fetchHotProductsLongJob then
fetchNewProductsLongJob then
fetchNewProductsLongJob done
fetchNewProducts done
fetchNewProducts job done
答案 2 :(得分:0)
您可以使用await
Future<List<HotProducts>> _loadHotProducts;
Future<List<NewProducts>> _loadNewProducts;
Future<List<Promotion>> _loadPromotions;
Future<List<LatestSoldItem>> await _loadLatestSoldItem;
userId = result;
_loadHotProducts = await HotProductsApiClient().fetchHotProducts(http.Client(), userId);
_loadNewProducts = await NewProductApiClient().fetchNewProducts(http.Client(), userId);
_loadPromotions = await PromotionApiClient().fetchPromotion(http.Client());
_loadLatestSoldItem = await LatestSoldApiClient().fetchProducts(http.Client(), userId);
setState(() {});
您需要使方法异步。