如何在Dart中从流中调用流

时间:2019-07-06 02:44:38

标签: flutter dart

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

为此,我正在使用StreamBuilder和Stream,该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运行时获得所有结果。

1 个答案:

答案 0 :(得分:1)

我遵循了pskink的建议,并做到了:

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

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

  

yield *(发音为每个)的设计目的是为了避开   这个问题。 yield *之后的表达式必须表示另一个   (子)序列。 yield *的作用是插入   子序列到当前正在构建的序列中,就好像我们   每个元素都有自己的产量。我们可以重写代码   使用yield-each如下:

然后我可以将yield放在downloadIdentifiers内,值将被传递。