如何在Dart中进行嵌套的httpClient调用,多个异步/等待

时间:2019-05-07 17:53:45

标签: dart async-await

我必须使用httpClient打几个电话。其中一个以json格式获取给定博客帖子的“主要”数据,然后我必须使用该信息再次调用与该帖子相关的其他媒体信息。

这是所有多个帖子的内容,因此本质上我在做:

Future<List<String>> fetchPosts() async {
  response = await httpClient.get('http://somewebsite/topPosts');
  data = json.decode(response.body) as List;
  data.map((singlePost) {
    mediaID = singlePost["mediaID"];
    //second await call below, this won't work as-is, correct?
    finalData = await httpClient.get('http://somewebsite/media/$mediaID')

我希望这是有道理的,我正在尝试完成。本质上,我正在嵌套http调用。不确定这样做的“好方法”,也许使用Future.wait(),欢迎任何建议。

1 个答案:

答案 0 :(得分:1)

 data.map((singlePost) {
    mediaID = singlePost["mediaID"];
    //second await call below, this won't work as-is, correct?
    finalData = await httpClient.get('http://somewebsite/media/$mediaID')

是行不通的。首先,您在提供给await的回调中使用map,但使用await can be used only in a function marked async

async标记回调后,代码可能无法满足您的要求。 List.map()用于转换 List。例如,您将使用它从String的列表中创建int的列表,反之亦然。在这种情况下,您将生成Iterable个列表(实际上是Future)。您不会在任何地方存储该Future列表,因此await永远不会在完成后得到通知。

您可能会喜欢的东西:

final futures = data.map((singlePost) async { ... });
await Future.wait(futures);

这将等待所有操作完成。但是,您的另一个问题是您的map回调确实:

finalData = await httpClient.get('http://somewebsite/media/$mediaID')

这意味着每个回调将以某种未指定的顺序破坏finalData变量(无论是什么)。