首页 > 解决方案 > 如何从 Dart 中的流中调用流

问题描述

我想输出进度消息,同时我下载文件并在我的颤振应用程序中填充我的数据库。

为此,我使用了一个 StreamBuilder 和一个在执行工作时产生状态消息更新的 Stream。

到目前为止一切顺利,但现在除了我的状态消息之外,我还想显示一些有关下载进度的详细信息。据我了解,我可以将下载进度包装在另一个流中,但现在我对如何从状态更新流中调用该流有点困惑。

代码现在看起来像这样:

  Stream<String> _upsertResult(context) async* {
    yield "Downloading Identifiers... (1/6)";
    await IdentifierService.downloadIdentifiers();
    yield "Upserting Identifiers... (2/6)";
    await IdentifierService.upsertIdentifiers();
    yield "Downloading Locations... (3/6)";
    await LocationService.downloadLocations();
    yield "Upserting Locations... (4/6)";
    await LocationService.upsertLocations();
    yield "Downloading Identifiables... (5/6)";
    await IdentifiableService.downloadIdentifiables();
    yield "Upserting Identifiables... (6/6)";
    await IdentifiableService.upsertIdentifiables();
    SchedulerBinding.instance.addPostFrameCallback((_) {
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => CurtainInformationScreen()),
      );
    });
  }

现在downloadIdentifiers()实现为 Future,但我可以将其重写为 Stream,以便能够产生下载进度状态更新。

我想我可以收听我创建的新 Stream 并在我的 _upsertResult Stream 中重新生成它,但我想知道这里是否有更优雅的解决方案来解决我的问题,比如等待 Stream 结束,但重新生成所有Stream 运行时的结果。

标签: flutterdart

解决方案


我按照pskink的建议做了这样的事情:

yield "Downloading Identifiers... (1/6)";
yield* IdentifierService.downloadIdentifiers();

根据http://dart.goodev.org/articles/language/beyond-async#yield

yield*(发音为 yield-each)语句旨在解决这个问题。yield* 后面的表达式必须表示另一个(子)序列。yield* 所做的是将子序列的所有元素插入到当前正在构建的序列中,就好像我们对每个元素都有一个单独的 yield。我们可以使用 yield-each 重写我们的代码,如下所示:

然后我就可以yield进去downloadIdentifiers,价值将被传递。


推荐阅读