【问题标题】:Dart Future.wait for multiple futures and get back results of different typesDart Future.wait 等待多个期货并返回不同类型的结果
【发布时间】:2020-07-21 03:26:39
【问题描述】:

我正在使用 Flutter 从服务器下载 3 组不同的数据,然后对所有 3 组进行处理。我可以这样做:

List<Foo> foos = await downloader.getFoos();
List<Bar> bars = await downloader.getBars();
List<FooBars> foobars = await downloader.getFooBars();

processData(foos, bars, foobars);

但我更喜欢并行异步下载所有 3 个数据集。我已经看到 Dart 有这个 Future.wait method:

Future<List<T>> wait <T>(
   Iterable<Future<T>> futures, {
   bool eagerError: false, 
   void cleanUp(
      T successValue
   )
}) 

但是看起来这只会返回相同类型 (T) 的值。我有 3 种不同的类型,所以我不知道如何使用它并取回我的 3 个数据集。

实现这一目标的最佳替代方法是什么?

谢谢!

【问题讨论】:

    标签: flutter asynchronous dart concurrency future


    【解决方案1】:

    您需要将每个Future&lt;T&gt;s 调整为Future 的通用类型。你可以使用Future&lt;void&gt;:

    List<Foo> foos;
    List<Bar> bars;
    List<FooBars> foobars;
    
    await Future.wait<void>([
      downloader.getFoos().then((result) => foos = result),
      downloader.getBars().then((result) => bars = result),
      downloader.getFooBars().then((result) => foobars = result),
    ]);
    
    processData(foos, bars, foobars);
    

    或者,如果您更喜欢await 而不是.then(),则Future.wait 调用可能是:

    await Future.wait<void>([
      (() async => foos = await downloader.getFoos())(),
      (() async => bars = await downloader.getBars())(),
      (() async => foobars = await downloader.getFooBars())(),
    ]);
    

    【讨论】:

      【解决方案2】:

      我认为不可能以超级好的方式进行。你所能做的就是这样:

      void main() async {
        List<List<dynamic>> result = await Future.wait<List<dynamic>>([
          getStringData(),
          getIntData(),
        ]);
      
        print(result[0]);
        print(result[1]);
      }
      
      Future<List<String>> getStringData() {
        return Future.value(["a", "b"]);
      }
      
      Future<List<int>> getIntData() {
        return Future.value([1, 2]);
      }
      

      【讨论】:

        【解决方案3】:

        嗯,类型 T 是泛型类型

        您了解自己的类型,因此可以使用它们。

        如果您使用的是FutureBuilder,您可以使用它访问不同的结果。 (与Future.wait 方法中的顺序相同)

        snapshot.data[0] // maybe type List<Foo>
        snapshot.data[1] // maybe type List<Bar>
        snapshot.data[2] // maybe type String
        

        【讨论】:

          【解决方案4】:

          我想说正确的答案是使用官方的async包和FutureGroup

          void main()  {
            Future<String> future1 = getData(2);
            Future<String> future2 = getData(4);
            Future<String> future3 = getData(6);
            FutureGroup futureGroup = FutureGroup();
            futureGroup.add(future1);
            futureGroup.add(future2);
            futureGroup.add(future3);
            futureGroup.close();
            futureGroup.future.then((value) => {print(value)});
          }
          
          Future<String> getData(int duration) async {
            await Future.delayed(Duration(seconds: duration)); //Mock delay
            return "This a test data";
          }
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-25
            • 1970-01-01
            • 2021-01-01
            • 2019-06-22
            • 1970-01-01
            • 2020-10-31
            • 2019-10-29
            • 2017-06-02
            相关资源
            最近更新 更多