对java.util.concurrent.Flow.Processor <t,r>的良好实现/支持

时间:2017-11-17 12:11:41

标签: reactive-programming java-9 project-reactor reactive-streams java-flow

最近,我通过projectreactor.io找到了对Publisher的良好支持:

Flux.create(fluxSink -> {
           for (int i = 0; i < 10; i++)
            fluxSink.next(i);
           fluxSink.complete();
        })
                .map(...)
                .subscribe(...);

对Proccessor有什么好的支持吗? 我的意思是类似或类似的东西:

XXX process = new XXX((inputValue, output) -> {
    if(inputValue == 0)
       output.error();
    else
       output.next(inputValue);
});

publisher.subscribe(process);  
process.subscribe(...);

如果没有,我该如何实现自己或为什么我不能这样做?

更新1:

经过讨论(见评论),在我的用例中,我需要使用flatMap(参见答案),我的问题是处理器的良好实现,这意味着一些功能,如果它失败,我能够采取控制并发出错误。我认为flatMap会给你足够的功能。就我而言,我用过:

        import org.jsoup.Jsoup;

        Flux.just("url")
            .flatMap(url -> {
                try {
                    Document document = Jsoup.connect(url).get();
                    return Flux.just(document);
                } catch (IOException e) {
                    return Flux.error(e);
                }
            })
            .subscribe();

3 个答案:

答案 0 :(得分:3)

您可能正在寻找 SubmissionPublisher ,这似乎与反应堆中的 Flux 实施类似:

  

异步发出提交的Flow.Publisher(非空)   当前订阅者关闭之前的项目。每个电流   订阅者以相同的顺序接收新提交的项目,除非   遇到丢弃或异常。使用SubmissionPublisher   允许项目生成器充当兼容的反应流发布者   依靠掉落处理和/或阻止流量控制。

注意 :链接中共享自定义示例Flow.Processor,可进一步自定义以处理onErrorconsume您的用例所需的方法实现。

答案 1 :(得分:2)

根据您对用例的描述,我不希望您确实需要Processor。而是使用flatMap来触发异步URL提取。与所有Reactive Streams运算符一样,flatMap将默认在发生错误时立即停止。

您可能需要处理器的唯一部分是生成Flux<URL> ,如果您事先不知道网址(否则,Flux.fromIterableFlux.just(...)会做得很好。

如果您需要将结果分发给多个Subscriber而不重新触发请求,请查看publish().connect()和/或cache()

答案 2 :(得分:1)

这实际上取决于你想做什么。

Flux上的大多数方法都创建了这样的处理器,并将它们作为Flux返回,确保它们以正确的方式订阅上游Flux

因此,如果您的Processor应为其收到的每个人发出一个事件,但另一个map是您创建Processor的简单方法。如果它为收到的每个事件创建了多个(或没有)事件,请使用flatMap等等。

您可以通过链接这些方法来创建更复杂的方法。 我希望99%的用例可以这样处理。

如果这还不够,请考虑subscribe的各种重载,您可以使用Consumer处理Flux的元素以及错误,完成和订阅等状态更改。您可以将这些内容与Flux.create(fluxSink -> ...)相结合,以构建非常灵活的Processors