【发布时间】:2018-05-01 02:46:48
【问题描述】:
最近,我决定使用 projectreactor.io (io.projectreactor:3.1.1) 尝试 spring 5。
有谁知道使用此功能的最佳情况是什么?使用它们各自的优缺点以及应该在哪里使用它们?
好的例子会有所帮助。
【问题讨论】:
标签: reactive-programming project-reactor reactive-streams
最近,我决定使用 projectreactor.io (io.projectreactor:3.1.1) 尝试 spring 5。
有谁知道使用此功能的最佳情况是什么?使用它们各自的优缺点以及应该在哪里使用它们?
好的例子会有所帮助。
【问题讨论】:
标签: reactive-programming project-reactor reactive-streams
这里有两种截然不同的运算符:
Flux 本身上工作的运算符transform 和 transformDeferred 用于代码互化当您定期编写运算符链并且您的应用程序中有常见的运算符使用模式时,您可以使用transform 和transformDeferred 来共享此代码或给它一个更具描述性的名称。
两者之间的区别在于何时应用了相互化的运算符: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()已经不存在了……
我发现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
【讨论】: