逐一运行“未来”

时间:2019-11-13 13:06:44

标签: flutter

现在我有了这个脚本

  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

我该如何解决?还是有更好的方法?

3 个答案:

答案 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和所有httpfuture工作
您可以在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

正确的演示 enter image description here

删除一些等待后的问题代码

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(() {});

您需要使方法异步。