1. 简介

本文将深入探讨 RxJava 中的 Maybe 类型——它代表一种能发射单个值、空完成或报告错误的响应式流。

2. Maybe 类型解析

Maybe 是一种特殊的 Observable,它只能发射零个或一个数据项,并在计算失败时报告错误。

从功能上看,Maybe 就像是 Single 和 Completable 的结合体。这些精简类型(包括 Maybe)都提供了 Flowable 的部分操作符。这意味着只要操作对 0 或 1 个数据项有意义,我们就能像使用 Flowable 一样使用 Maybe

由于最多只能发射一个值,Maybe 不像 Flowable 那样支持背压处理:

Maybe.just(1)
  .map(x -> x + 7)
  .filter(x -> x > 0)
  .test()
  .assertResult(8);

Maybe 源可以订阅三种信号:

  • onSuccess:发射单个值
  • onError:报告错误
  • ⚠️ onComplete:空完成
Maybe.just(1)
    .subscribe(
        x -> System.out.print("发射数据: " + x),
        ex -> System.out.println("错误: " + ex.getMessage()),
        () -> System.out.println("完成。无数据")
     );

上述代码会输出 发射数据: 1,因为源成功发射了值。

对于相同订阅方式:

  • Maybe.empty().subscribe(...) 会输出 "完成。无数据"
  • Maybe.error(new Exception("error")).subscribe(...) 会输出 "错误: error"

Maybe 的这三个事件是互斥的。即 onSuccess 后不会调用 onComplete,这点与 Flowable 不同——Flowable 在流完成时即使有 onNext 调用也会触发 onComplete

Single 没有 onComplete 信号,因为它设计用于处理"发射一个值或失败"的场景。
*Completable 缺少 onSuccess*,因为它只处理"完成/失败"场景。

Maybe 的另一个实用场景是与 Flowable 结合。通过 firstElement() 方法可将 Flowable 转换为 Maybe:

Flowable<String> visitors = ... // 假设这是访客流
visitors
  .skip(1000)
  .firstElement()
  .subscribe(
    v -> System.out.println("第1000位访客: " + v + " 获得奖品"), 
    ex -> System.out.print("错误: " + ex.getMessage()), 
    () -> System.out.print("需要更多推广活动"));

3. 总结

本文快速介绍了 RxJava Maybe 的使用方式,以及它与 Flowable、Single、Completable 等响应式类型的关系。

完整代码示例可在 GitHub 获取。


原始标题:RxJava Maybe