以异步方式使用 .map()、.where() 等迭代助手?

Posted

技术标签:

【中文标题】以异步方式使用 .map()、.where() 等迭代助手?【英文标题】:Use iteration helpers like .map(), .where(), etc in an async manner? 【发布时间】:2019-07-19 00:42:20 【问题描述】:

简短: toList()makeMaker 之前执行,导致 markers 具有 null 对象。

Long:在 Firestore 中,我有 tablegame 集合,在 table 内部,有一个 game 字段(type=reference)。使用StreamBuilder,我可以访问tables。我遍历tables 并尝试使用get 用真实数据填充他们的game 字段,如下所示;

if (snapshot.hasData) 
            tabledocs = snapshot.data.documents;
            markers = tabledocs
                .map((tabledoc) 
              DocumentReference gameref = tabledoc.data['game'];
              //game field is a reference type field which points to another collection
              gameref.get().then((gdoc) 
                tabledoc.data['game'] = gdoc;
                Marker marker = makeMarker(tabledoc);  //<--------Executes later
                return marker;
              );
            ).toList();                               //<--------Executes first
          

因为gameref.get().then() 需要时间,所以底部的toList() 在每个标记生成并添加到markers 之前执行。

如果有 3 个标记从 Firestore 返回,我们的 markers 是一个由 3 个 null markers 组成的数组。我认为makeMarker(..) 很可能还没有执行。

有没有办法让map 方法等待gets 完成,然后用非空值初始化markers 数组?或者你能告诉我另一种方法来完成我想要的。

【问题讨论】:

【参考方案1】:

你可以使用

await for(var tabledoc of tabledocs)  


或者如果不需要按顺序执行项目(结果将按照原始项目的顺序)

var markers = await Future.wait(tabledocs
  .map((tabledoc) 
    DocumentReference gameref = tabledoc.data['game'];
          //game field is a reference type field which points to another collection
    var gdoc = await gameref.get();
    tabledoc.data['game'] = gdoc;
    Marker marker = makeMarker(tabledoc);
    return marker;
  );

【讨论】:

非常酷。我从未见过await for,所以我会选择Future.wait()。但是await for 读起来更清晰,因为我现在看到了它。 你不应该在StreamBuilder中做这样的事情。最好在initStatedidChangeDependencies 中执行此操作,并使用setState(...) 将结果存储在字段中并启动重建。您可能需要将代码移动到您从 initState 调用的方法中才能使用 async 从 Firestore 获取它们可能是不使用 StreamBuilder 的一个很好的理由,否则每次重建小部件时都会获取它们。 好的,我会根据您的指导尽可能多地更改代码。很快就会回信。一如既往的感谢 @GünterZöchbauer 感谢您带领我走向正确的道路

以上是关于以异步方式使用 .map()、.where() 等迭代助手?的主要内容,如果未能解决你的问题,请参考以下文章

如何以与 np.where 相同的方式使用 Tensorflow.where?

在Array#map()中异步/等待

jquery的post异步请求

实体框架 - 使用 where 条件进行异步选择

将额外参数传递给异步映射

将额外参数传递给异步映射