跳到主要内容

复用操作符用法

Doubao 中英对照 Mutualizing Operator Usage

目录

从整洁代码的角度来看,代码复用通常是一件好事。Reactor 提供了若干模式,可以帮助您复用和共用代码,尤其是那些您可能想在代码库中反复使用的操作符或操作符组合。如果把一条操作符链想象成一份菜谱,您就可以创建一本由操作符菜谱组成的“烹饪书”。

1. 使用 transform 操作符​

transform 操作符让您可以把操作符链中的一段封装进一个函数。这个函数会在组装时应用到一条原始操作符链上,用被封装的操作符对其进行增强。这样做会把相同的操作应用到序列的所有订阅者身上,本质上等同于直接把这些操作符链式串起来。以下代码展示了一个示例:

Function<Flux<String>, Flux<String>> filterAndMap =
f -> f.filter(color -> !color.equals("orange"))
.map(String::toUpperCase);

Flux.fromIterable(Arrays.asList("blue", "green", "orange", "purple"))
.doOnNext(System.out::println)
.transform(filterAndMap)
.subscribe(d -> System.out.println("Subscriber to Transformed MapAndFilter: "+d));

下图展示了 transform 操作符如何封装数据流:

transform 操作符:封装数据流

上例产生如下输出:

blue
Subscriber to Transformed MapAndFilter: BLUE
green
Subscriber to Transformed MapAndFilter: GREEN
orange
purple
Subscriber to Transformed MapAndFilter: PURPLE

2. 使用 transformDeferred 操作符​

transformDeferred 操作符与 transform 类似,同样让您可以把操作符封装进一个函数。主要区别在于:这个函数是按订阅者分别应用到原始序列上的。也就是说,该函数实际上可以为每次订阅生成一条不同的操作符链(通过维护某些状态)。以下代码展示了一个示例:

AtomicInteger ai = new AtomicInteger();
Function<Flux<String>, Flux<String>> filterAndMap = f -> {
if (ai.incrementAndGet() == 1) {
return f.filter(color -> !color.equals("orange"))
.map(String::toUpperCase);
}
return f.filter(color -> !color.equals("purple"))
.map(String::toUpperCase);
};

Flux<String> composedFlux =
Flux.fromIterable(Arrays.asList("blue", "green", "orange", "purple"))
.doOnNext(System.out::println)
.transformDeferred(filterAndMap);

composedFlux.subscribe(d -> System.out.println("Subscriber 1 to Composed MapAndFilter :"+d));
composedFlux.subscribe(d -> System.out.println("Subscriber 2 to Composed MapAndFilter: "+d));

下图展示了 transformDeferred 操作符如何按订阅者进行变换:

compose 操作符:按订阅者变换

上例产生如下输出:

blue
Subscriber 1 to Composed MapAndFilter :BLUE
green
Subscriber 1 to Composed MapAndFilter :GREEN
orange
purple
Subscriber 1 to Composed MapAndFilter :PURPLE
blue
Subscriber 2 to Composed MapAndFilter: BLUE
green
Subscriber 2 to Composed MapAndFilter: GREEN
orange
Subscriber 2 to Composed MapAndFilter: ORANGE
purple