【问题标题】:How to return Future<List<Object>> from List<DocuementReference>>?如何从 List<DocumentReference>> 返回 Future<List<Object>>?
【发布时间】:2021-08-23 08:45:20
【问题描述】:

我正在尝试创建一种将列表转换为 Future 的方法。 这是我创建的方法。

    static Future<List<Product?>> fromProductRefList(
      List<DocumentReference> ref) async {
      List<Product> shopProductList = [];
      ref.forEach((productRef) async {
        final productDoc = productRef.get();
        final product = await Product.fromDocument(await productDoc);
        shopProductList.add(product!);
    });

      print('shopProductList: $shopProductList');
      return shopProductList;
  }

并称它为肘,

  void mapProductToState() async {
    emit(state.copyWith(status: MyProductStatus.loadding));
    final shop = _shopBloc.state.shop;
    List<Product?> productList = [];

    if (shop.shopProductRef.isNotEmpty) {
      final productList = Product.fromProductRefList(shop.shopProductRef);
    }

    emit(state.copyWith(
      shop: shop,
      productList: productList,
      status: MyProductStatus.loaded,
    ));
  }

VScode 没有显示错误,但是当我运行代码时,fromProductRefList 返回空列表。似乎 fromProductRefList 并没有等待 Document 从数据库中实际 get() 并返回。

当我在返回 shopProductList 之前在 fromProductRefList 中添加第二个延迟时,一切都按预期工作。

我已经阅读了关于 stackoverflow 的另一个问题,建议使用 asyncMap(),但我不确定如何在我的情况下应用它。

编辑: 当我添加延迟时,该方法返回没有任何问题。如果没有,它将返回一个空列表

static Future<List<Product?>> fromProductRefList(
      List<DocumentReference> ref) async {
    List<Product> shopProductList = [];
    ref.forEach((productRef) async {
      final productDoc = productRef.get();
      final product = await Product.fromDocument(await productDoc);
      shopProductList.add(product!);
    });

    await Future.delayed(const Duration(milliseconds: 500));

    print('shopProductList: $shopProductList');
    return shopProductList;
  }

谢谢。

【问题讨论】:

    标签: firebase flutter dart google-cloud-firestore


    【解决方案1】:

    您缺少 await 关键字,实际上是在等待呼叫。它只会编译,因为您还声明了一个名为 productListnew 变量,隐藏了已经存在的变量。

    所以这一行:

    final productList = Product.fromProductRefList(shop.shopProductRef);
    

    应改为:

    productList = await Product.fromProductRefList(shop.shopProductRef);
    

    此外,这并不像你认为的那样:

    ref.forEach((productRef) async {
    

    它确实等待每个调用。请使用普通的for 流控制结构和await 异步调用,而不是forEach 方法。 forEach 方法不会等待从方法返回的 Futures。

    【讨论】:

    • 嗨@nvoigt,感谢您的回答。我做了你提到的改变,但问题仍然存在。
    • 你确定一肘是正确的选择吗?它看起来相当复杂,应该是一个成熟的 BLoC。您的 async 方法返回 void 而不是 future 的事实让我认为您在尚未发布的部分中遗漏了更多内容。
    • 我已经编辑了我的问题以包含一个临时解决方案,以使我的方法有效。我认为该方法没有等待 forEach 函数完成
    • 更新了我的答案。
    • 感谢 nvoigt!尽管我觉得 forEach 的行为应该与常规 for 相似,但我觉得它确实很奇怪,但它仍然可以完美运行。
    猜你喜欢
    • 1970-01-01
    • 2022-07-26
    • 1970-01-01
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 2016-09-21
    相关资源
    最近更新 更多