【问题标题】:Getting values from Future instances从 Future 实例中获取值
【发布时间】:2017-10-05 06:41:30
【问题描述】:

我的数据是这样的:

{
  "five": {
    "group": {
      "one": {
        "order": 2
      },
      "six": {
        "order": 1
      }
    },
    "name": "Filbert",
    "skill": "databases"
  },
  "four": {
    "group": {
      "three": {
        "order": 2
      },
      "two": {
        "order": 1
      }
    },
    "name": "Robert",
    "skill": "big data"
  },
  "one": {
    "name": "Bert",
    "skill": "data analysis"
  },
  "seven": {
    "name": "Colbert",
    "skill": "data fudging"
  },
  "six": {
    "name": "Ebert",
    "skill": "data loss"
  },
  "three": {
    "name": "Gilbert",
    "skill": "small data"
  },
  "two": {
    "name": "Albert",
    "skill": "non data"
  }
}

我正在使用以下功能:

  Future retrieve(String id) async {
    Map employeeMap = await employeeById(id); //#1
    if (employeeMap.containsKey("group")) { //#2
      Map groupMap = employeeMap["group"];
      Map groupMapWithDetails = groupMembersWithDetails(groupMap); #3
      // above returns a Mamp with keys as expected but values 
      // are Future instances.
      // To extract values, the following function is
      // used with forEach on the map
      futureToVal(key, value) async { // #4
        groupMapWithDetails[key] = await value; 
      }
      groupMapWithDetails.forEach(futureToVal); // #4
    }
    return groupMapWithDetails;
   }
  1. 我从数据库 (Firebase) 访问一名员工(以 aMap
  2. 如果员工是领导者(有一个关键的“组”)
  3. 我通过调用单独的函数从数据库中获取组中每个员工的详细信息。
  4. 由于该函数返回一个映射,其值是Future 的实例,我想从中提取实际值。为此,在地图上调用 forEach。 但是,我只将 Future 的实例作为值。

如何获得实际值?

【问题讨论】:

    标签: dart dart-async


    【解决方案1】:

    没有办法从异步执行返回到同步执行。

    要从Future 中获取值,有两种方法

    将回调传递给then(...)

    theFuture.then((val) {
      print(val);
    });
    

    或使用async/await 以获得更好的语法

    Future foo() async {
      var val = await theFuture;
      print(val);
    }
    

    【讨论】:

    • 真的没有办法访问 Dart Future 的值吗?类似于 SCALA 的 Await.result(someFuture, 5.seconds) ???
    • @kosiara-BartoszKosarzycki 我不明白你的问题。您可以使用await,如上所示。但是,无法同步获取该值,因为否则它一开始就不会异步。
    • 我正在寻找一种将 Future 转换为同步调用的方法。与 SCALA 的前一个示例一样 - 调用等待 Future 的值 5 秒,如果无法获得未来值则失败。 IE。 var synchedVal = Await.result(someFuture, 5.seconds) 然后 synchedVal 可以从非异步函数返回 - 作为类型而不是作为 Future。在 await 示例中,您给出的值只能在 async 函数的范围内使用。
    • Dart 中没有这样的东西。 Scala 所做的看起来像一个丑陋的 hack。如果你有线程,这可能会起作用,但 Dart 没有线程,而且 Dart 也被构建为可编译为 JS,在 JS 中没有办法实现这样的“hack”。
    【解决方案2】:

    您无需等待 await value 表达式完成。

    forEach 调用遍历映射条目并为每个条目启动异步计算。然后放弃该计算的未来,因为forEach 不使用其函数的返回值。 然后在任何异步计算完成之前返回地图,因此地图中的值仍然是期货。它们最终会变成非期货,但你不知道什么时候完成。

    不要使用forEach 调用,试试:

    await Future.wait(groupMapWithDetails.keys.map((key) async {
      groupMapWithDetails[key] = await groupMapWithDetails[key];
    });
    

    这对地图中的每个键执行异步操作,并等待它们全部完成。之后,地图应该具有非未来值。

    【讨论】:

      猜你喜欢
      • 2021-10-05
      • 2021-04-06
      • 2022-10-24
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-07
      • 2014-12-08
      • 1970-01-01
      相关资源
      最近更新 更多