【问题标题】:How to iterate over a Stream in Dart如何在 Dart 中遍历 Stream
【发布时间】:2020-02-22 04:11:41
【问题描述】:

在学习了多年的 Python 之后,我正在使用 Dart 学习绳索。 我对 Streams 有点困惑,如果有任何其他特定的解决方案可以用于我的具体情况。

我正在构建一个 API 驱动的应用程序,我需要动态填充 ListView 而无需等待所有 HTTP 调用完成。 目前我正在使用一个 Stream 来填充一个 List 并返回:

类似这样的:

var scraperList = List<Api> ();

Stream<List<Api>> get getFiles (String id) async* {
    var res = await http.post('${baseUrl}/folder/list/{id}');
    if (res.statusCode == 200) {
      var jsonResult = jsonDecode(res.body);
      jsonResult = jsonResult['content'];
      List<dynamic> body = jsonResult;
      List<Api> result = body.map((dynamic item) => ApiModel.apiFiles(item),).toList();
}

现在,这是我迷路的地方,因为 API 充当一种文件/文件夹存储,如果它们是“文件”,我需要产生结果,并使用文件夹的 id 重复调用并获取该文件夹中的“文件”并继续这样做,直到我递归地获取每个文件夹中的所有文件。

关键是我想继续提供该 Stream 并在结果到达时获得结果,而无需等待所有调用完成。

我现在迷失的地方是这部分


      // THIS IS THE PART I NEED TO UNDERSTAND YET
      for (item in result){
        if (item.type == 'file'){
          yield filelist.add(0, item);}
        else { I NEED TO MAKE A CALL AGAIN TO THIS FUNCTION TO GET THE FOLDER CONTENT
             THE CALL AGAIN }

我如何迭代这个 API,递归地获取每个文件夹中的所有文件并继续提供该 Stream? 有一个更好的方法吗? 在 python 中,有很多方法可以跨类共享列表等,但我仍然对如何在 Dart 中动态实现这一点感到困惑。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    你需要的是 yield* 和 await

    检查一下

    import 'dart:async';
    
    void main() {
    
      final folder1 = Future.value({"a","b","c","d"});
      final folder2 = Future.value({"a","b","c","d",folder1});
      final folder3 = {"a","b","c","d",folder1,folder2}; //what you get initially
    
      Stream printElement(list) async*{
    
         for(dynamic element in list){
    
          if(element is String){
            yield element;
           }else{
            yield* printElement(
            await(element));  //make your http call here for your nested folder
            }
    
         };
      }
    
      printElement(folder3).listen((element){
          print(element);
      });
    
    }
    

    您还可以在dartz packageEither 中使用更多类型安全代码

    import 'dart:async';
    import 'package:dartz/dartz.dart';
    
    class MyFile{
    
      final String fileName ;
    
      MyFile(this.fileName);
    
      @override
      String toString() {
        return this.fileName;
      }
    }
    
    class MYFolder{
    
      final String folderName;
      final List<Either<Future<MYFolder>,MyFile>> files; //files can be Either file or Future of folder from HTTP
    
      MYFolder(this.folderName, this.files);
    
      @override
      String toString() {
        return this.folderName;
      }
    }
    
    void main() {
    
      //leaf folders
    
      final foldera = MYFolder("foldera",[Right(MyFile("a")),Right(MyFile("a")),Right(MyFile("a")),Right(MyFile("a"))]);
      final folderb = MYFolder("folderb",[Right(MyFile("b")),Right(MyFile("b")),Right(MyFile("b")),Right(MyFile("b"))]);
      final folderc = MYFolder("folderc",[Right(MyFile("c")),Right(MyFile("c")),Right(MyFile("c")),Right(MyFile("c"))]);
      final folderd = MYFolder("folderd",[Right(MyFile("d")),Right(MyFile("d")),Right(MyFile("d")),Right(MyFile("d"))]);
    
      //                    ...foldera
      //                   - folderb
      //        -  folder1
      //
      //folder3 -  folder2
      //                  ... folderc
      //                  - folderd
      //
      // --triple dot notation for folding elements in lists ,it is just a shortcut for populating lists
    
      final  folder1 = Future.value(MYFolder("folder1", [...foldera.files,Left(Future.value(folderb))]));
      final folder2 = Future.value(MYFolder("folder2", [...folderc.files, Left(Future.value(folderd))]));
      final folder3 = MYFolder("folder3",[Left(Future.value(folder1)),Left(Future.value(folder2))]); //what you get initially
    
      Stream printFilesIn(MYFolder folder) async*{
    
        print("Current folder is $folder");
    
         for(Either file in folder.files){
          if(file is Right){
            yield file.value;
          }else{
            yield* printFilesIn(
            await(file as Left).value); //make your http call here for your nested folder
            }
          };
      }
    
      printFilesIn(folder3).listen(print);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 2023-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多