如何异步处理akka中的多级源代码

时间:2018-01-05 16:10:24

标签: java akka akka-stream

我有一个列表列表,我期待使用akka运行它,并希望在完成所有子列表处理后执行操作。但是,在所有孩子完成之前,“完成”正在运行。

基本上我正在尝试读取excel中的所有工作表,然后从excel中读取每一行。为此,我希望使用akka单独处理每张纸,并且在每张纸上,我希望单独处理每一行。

示例代码:

    List<List<String>> workbook = new ArrayList<List<String>>();
    List<String> Sheet1 = new ArrayList<String>();

    Sheet1.add("S");
    Sheet1.add("a");
    Sheet1.add("d");

    List<String> Sheet2 = new ArrayList<String>();

    Sheet2.add("S");
    Sheet2.add("a1");
    Sheet2.add("d");

    workbook.add(Sheet1);
    workbook.add(Sheet2);

    final ActorSystem system = ActorSystem.create("Sys");

    final ActorMaterializer materializer = ActorMaterializer.create(system);

    Source.from(workbook).map(sheet -> {
        return Source.from(sheet).runWith(Sink.foreach(data -> {
            System.out.println(data);
            Thread.sleep(1000);
        }), materializer).toCompletableFuture();
    }).runWith(Sink.ignore(), materializer).whenComplete((a, b) -> {
        System.out.println("Complete");
    });
    system.terminate();

当前输出为:

S
S
Complete
a
a1
d
d

预期输出为:

S
S
a
a1
d
d
Complete

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您使用“流中的流”可能会使流程过于复杂。

您可以使用Flow.flatMapConcat。我只能在scala中提供一个示例,但希望它可以轻松转换为java:

val flattenFlow : Flow[List[String], String, NotUsed] = 
  Flow[List[String].flatMapConcat(sheet => Source(sheet))

val Source[String] flattenedSource = Source(worksheet).via(flattenFlow)

a blog post有一个在java中使用flatMapConcat的示例,但我不知道我的猜测类型Flow.of(List<String>.class)是否是有效代码。