使用 Project Reactor 的 Flux

980 阅读2分钟

Project Reactor 是一个用于实现响应式编程的库,它提供了两个核心类型:FluxMono。本文将重点介绍 Flux,介绍创建 Flux 的不同方法以及它们的区别,并通过代码示例演示 Flux 的常见用法。

创建 Flux 的方法

  1. Flux.just():使用提供的元素创建一个包含静态值的 Flux。
Flux<String> flux = Flux.just("Apple", "Banana", "Cherry");
  1. Flux.fromIterable():从一个 Iterable(如 List 或 Set)创建一个 Flux。
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
Flux<String> flux = Flux.fromIterable(fruits);
  1. Flux.fromArray():从一个数组创建一个 Flux。
String[] fruits = {"Apple", "Banana", "Cherry"};
Flux<String> flux = Flux.fromArray(fruits);
  1. Flux.fromStream():从一个 Java Stream 创建一个 Flux。
Stream<String> fruitStream = Stream.of("Apple", "Banana", "Cherry");
Flux<String> flux = Flux.fromStream(fruitStream);
  1. Flux.range():创建一个包含范围内整数的 Flux。
Flux<Integer> flux = Flux.range(1, 5); // 生成 1, 2, 3, 4, 5
  1. Flux.interval():创建一个包含固定时间间隔发出的递增序列的 Flux。
Flux<Long> flux = Flux.interval(Duration.ofSeconds(1)); // 每秒发出递增的整数
  1. Flux.empty():创建一个不包含任何元素的 Flux。
Flux<String> flux = Flux.empty();
  1. Flux.error():创建一个发出错误的 Flux。
Flux<String> flux = Flux.error(new RuntimeException("An error occurred"));
  1. Flux.create():使用 FluxSink 对象动态生成元素的 Flux。
Flux<String> flux = Flux.create(sink -> {
    sink.next("Apple");
    sink.next("Banana");
    sink.next("Cherry");
    sink.complete();
});
  1. Flux.generate():使用生成器函数逐个生成元素的 Flux。
Flux<Integer> flux = Flux.generate(() -> 0, (state, sink) -> {
    if (state >= 5) {
        sink.complete();
    } else {
        sink.next(state);
    }
    return state + 1;
});

Flux 的常见用法

订阅

要处理 Flux 中的元素,需要订阅它。订阅时可以提供回调函数,处理正常的元素、错误和完成事件。

Flux<String> flux = Flux.just("Apple", "Banana", "Cherry");
flux.subscribe(
    item -> System.out.println("Received: " + item),
    error -> System.err.println("Error: " + error.getMessage()),
    () -> System.out.println("Completed")
);

变换

使用 mapflatMap 进行同步和异步的元素变换。

Flux<Integer> flux = Flux.just("Apple", "Banana", "Cherry")
                          .map(String::length);

过滤

使用 filter 方法根据条件过滤元素。

Flux<String> flux = Flux.just("Apple", "Banana", "Cherry")
                         .filter(fruit -> fruit.startsWith("A"));

合并

使用 mergeconcat 将多个 Flux 合并为一个。

Flux<String> flux1 = Flux.just("Apple", "Banana");
Flux<String> flux2 = Flux.just("Cherry", "Date");

Flux<String> mergedFlux = Flux.merge(flux1, flux2);
Flux<String> concatenatedFlux = Flux.concat(flux1, flux2);

缓冲和窗口

使用 bufferwindow 方法将元素分组到 List 或子 Flux。

Flux<List<String>> bufferedFlux =Flux.just("Apple", "Banana", "Cherry", "Date")
                                       .buffer(2);

Flux<Flux<String>> windowedFlux = Flux.just("Apple", "Banana", "Cherry", "Date")
                                       .window(2);

异常处理

使用 onErrorResumeonErrorReturnretry 等方法处理错误。

Flux<String> flux = Flux.just("Apple", "Banana", "Cherry")
                         .map(fruit -> {
                             if ("Banana".equals(fruit)) {
                                 throw new RuntimeException("Banana error");
                             }
                             return fruit.toUpperCase();
                         })
                         .onErrorResume(e -> Flux.just("Recovered"));

结论

本文介绍了如何使用 Project Reactor 的 Flux 类型创建响应式序列,并通过代码示例演示了 Flux 的常见用法。Flux 提供了一种强大和灵活的方式来处理异步数据流,使得响应式编程在 Java 应用程序中变得更加简单。