【问题标题】:compose() vs. transform() vs. as() vs. map() in Flux and MonoFlux 和 Mono 中的 compose() vs. transform() vs. as() vs. map()
【发布时间】:2018-05-01 02:46:48
【问题描述】:

最近,我决定使用 projectreactor.io (io.projectreactor:3.1.1) 尝试 spring 5。

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

好的例子会有所帮助。

【问题讨论】:

    标签: reactive-programming project-reactor reactive-streams


    【解决方案1】:

    这里有两种截然不同的运算符:

    Flux 本身上工作的运算符

    transformtransformDeferred 用于代码互化

    当您定期编写运算符链并且您的应用程序中有常见的运算符使用模式时,您可以使用transformtransformDeferred 来共享此代码或给它一个更具描述性的名称。

    两者之间的区别在于何时应用了相互化的运算符:transform 在实例化时应用它们,而transformDeferred 在订阅时应用它们(允许动态选择添加的运算符)。

    查看reference documentation 了解更多详情和示例。

    注意:transformDeferred 在 3.3.0 之前的版本中被称为 compose

    as

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

    reactor-addonsMathFlux为例,对比一下:

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

    收件人:

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

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

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

    map 是关于数据的。当源中的每个元素可用时,它会对源中的每个元素应用 1-1 转换函数。

    在上面的 MathFlux 示例中,map 被连续用于将每个原始整数加 2,然后再次将序列中的每个数字乘以 10,最后第三次产生String out of每个总和。

    【讨论】:

    • 你能更新你的答案吗?看来compose()已经不存在了……
    【解决方案2】:

    我发现reference documentation 中的示例有点难以理解

    所以制作了以下程序来让我了解 transform vs compose 的概念。

    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;
                            };
    

    变换

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

    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));
    

    输出

    ReactordemoApplication - ONE>>>red
    ReactordemoApplication - TWO>>>red
    

    撰写

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

    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));
    

    输出

    ReactordemoApplication - ONE>>>RED
    ReactordemoApplication - TWO>>>red
    

    【讨论】:

      猜你喜欢
      • 2018-06-07
      • 1970-01-01
      • 2014-06-28
      • 2019-07-18
      • 1970-01-01
      • 2011-05-29
      • 1970-01-01
      • 2023-03-23
      • 2011-11-30
      相关资源
      最近更新 更多