在Flux和Mono中compose()与transform()vs. as()vs. map()

And*_*sha 10 reactive-programming project-reactor reactive-streams

最近,我决定尝试使用projectreactor.io的春天5 (io.projectreactor:reactor-test:jar:3.1.1).

有谁知道使用这个功能的最佳情况是什么?使用它们以及应该在哪里使用它们有什么缺点和优点?

好的例子会有所帮助.

Sim*_*slé 16

这里有两种截然不同的运营商类别:

Flux自己工作的运营商

transformcompose用于代码共享

当您定期组合运算符链并且在应用程序中有共同的运算符使用模式时,您可以通过使用compose和来共享此代码或为其提供更具描述性的名称transform.

两者之间的区别是被施加的mutualized操作符:transform在实例化应用它们,而compose在订阅它们应用于(允许添加的运营商的动态选择).

有关更多详细信息和示例,请查看参考文档.

as

这是一个方便的快捷方式应用Function到整个Flux同时保持整个代码在一个流畅的风格.一个例子是转换为Mono(如javadoc中所示),但它也可以帮助以工厂方法样式实现的外部运算符.

就拿reactor-addons MathFlux例如,和比较:

MathFlux.sumInt(Flux.range(1, 10)
                    .map(i -> i + 2)
                    .map(i -> i * 10))
        .map(isum -> "sum=" + isum);
Run Code Online (Sandbox Code Playgroud)

至:

Flux.range(1, 10)
    .map(i -> i + 2)
    .map(i -> i * 10)
    .as(MathFlux::sumInt)
    .map(isum -> "sum=" + isum)
Run Code Online (Sandbox Code Playgroud)

(这可以帮助您处理这样一个事实:与Kotlin不同,Java没有扩展方法:))

处理通过数据的数据的运算符 Flux

map是关于数据的.它将1-1转换函数应用于源中的每个元素,因为它们变得可用.

在上面的MathFlux示例中,map连续用于向每个原始整数添加2,然后再次将序列中的每个数字乘以10,然后在结束时第三次生成String每个总和.


Vas*_*sco 7

我发现参考文档中的示例 很难理解

所以制作了下面的程序来让我了解转换与组合的概念。

fnstatefull = flux -> {
                            Flux<String> f = flux.filter(color -> {
                                //only reds are allowed
                                return color.equalsIgnoreCase("red");   

                            });
                            //applies mapping 'toUpperCase' based on the external control 'toUpper'
                            if(toUpper) {
                                f= f.map(String::toUpperCase);
                            }
                            return f;
                        };
Run Code Online (Sandbox Code Playgroud)

转变

该运算符在通量实例化时应用。

fnstatefull 对下面的两个订阅者的行为方式相同。

    Flux<String> f = Flux.just("red", "green", "blue");
    toUpper = false;
    f = f.transform(fnstatefull);
    toUpper = true;

    f.subscribe(op -> log.error("ONE>>>" + op));
    toUpper = false;
    f.subscribe(op -> log.error("TWO>>>" + op));
Run Code Online (Sandbox Code Playgroud)

输出

ReactordemoApplication - ONE>>>red
ReactordemoApplication - TWO>>>red
Run Code Online (Sandbox Code Playgroud)

撰写

运算符在订阅通量时应用。

对于下面的每个订阅者,fnstatefull 的行为会有所不同。

    Flux<String> f = Flux.just("red", "green", "blue");
    toUpper = false;
    f = f.compose(fnstatefull);
    toUpper = true;

    f.subscribe(op -> log.error("ONE>>>" + op));
    toUpper = false;
    f.subscribe(op -> log.error("TWO>>>" + op));
Run Code Online (Sandbox Code Playgroud)

输出

ReactordemoApplication - ONE>>>RED
ReactordemoApplication - TWO>>>red
Run Code Online (Sandbox Code Playgroud)