Mono 的 doOnSuccess 与 doOnNext 之间有区别吗?
Is there a difference between doOnSuccess vs doOnNext for a Mono?
假设您有 Mono<Integer> someIntegerSource = Mono.just(5)
并且您想将其分配给一个变量。
这些代码片段之间有区别吗?
案例一:doOnSuccess
someIntegerSource.doOnSuccess(number -> this.myNumber = number)
案例 2:doOnNext
someIntegerSource.doOnNext(number -> this.myNumber = number)
案例 3:doOnSuccess + 然后(因为我想在发出单声道完成之前完成分配)
someIntegerSource.doOnSuccess(number -> this.myNumber = number).then()
阅读 class Mono
的文档并查看图表。他们对行为的解释非常清楚。几乎没有明显的差异,但它们仍然是:
Mono::doOnNext
在数据 成功发射 时触发,这意味着数据可用且存在。
Mono::doOnSuccess
在 Mono
成功完成 时触发 - 结果是 T
或 null
,这意味着正在处理无论数据状态如何,它本身都成功完成并执行,尽管数据不可用或不存在但管道本身成功。
Mono::then
作为方法链的结尾 returns Mono<Void>
完成和错误信号。
- 注意这里有效载荷被主动丢弃,这就是为什么
Mono<T>
变成 Mono<Void>
的原因。注意上面的两种方法不会丢掉payload。
这个答案缺少适当的说明性示例,因此我将对其进行修复:
非空 Mono
一个持有值的Mono
在数据发送成功时触发doOnNext
。这可能会使 doOnSuccess
混淆,但与此类触发器相反,当发出 any 成功值(包括空 Mono
时,会触发 doOnNext
,这仍然有效。
Mono.just("Hello World")
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On next: Hello World
On success: Hello World
空单声道
记住,虽然 Mono
是空的 (Mono.empty()
),它仍然是触发 doOnNext
的有效响应,但不是 doOnSuccess
,一个空的 Mono
可以理解为有效响应,但不代表包含有用值的所需输出。它的工作原理与 Optional.empty()
相同。 Mono
成功但没有触发 doOnNext
的实际有用值,因为它根本不发出任何值。
Mono.empty()
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
Mono.just("Hello World")
.mapNotNull(s -> null)
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
两者的结果相同:
On success: null
错误的单声道
为了完整起见,与空 Mono
进行对比,错误不会触发 doOnNext
或 doOnSuccess
,而是触发 doOnError
:
Mono.error(new RuntimeException("Something wrong"))
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On error: java.lang.RuntimeException: Something wrong
假设您有 Mono<Integer> someIntegerSource = Mono.just(5)
并且您想将其分配给一个变量。
这些代码片段之间有区别吗?
案例一:doOnSuccess
someIntegerSource.doOnSuccess(number -> this.myNumber = number)
案例 2:doOnNext
someIntegerSource.doOnNext(number -> this.myNumber = number)
案例 3:doOnSuccess + 然后(因为我想在发出单声道完成之前完成分配)
someIntegerSource.doOnSuccess(number -> this.myNumber = number).then()
阅读 class Mono
的文档并查看图表。他们对行为的解释非常清楚。几乎没有明显的差异,但它们仍然是:
Mono::doOnNext
在数据 成功发射 时触发,这意味着数据可用且存在。Mono::doOnSuccess
在Mono
成功完成 时触发 - 结果是T
或null
,这意味着正在处理无论数据状态如何,它本身都成功完成并执行,尽管数据不可用或不存在但管道本身成功。Mono::then
作为方法链的结尾 returnsMono<Void>
完成和错误信号。- 注意这里有效载荷被主动丢弃,这就是为什么
Mono<T>
变成Mono<Void>
的原因。注意上面的两种方法不会丢掉payload。
- 注意这里有效载荷被主动丢弃,这就是为什么
这个答案缺少适当的说明性示例,因此我将对其进行修复:
非空 Mono
一个持有值的Mono
在数据发送成功时触发doOnNext
。这可能会使 doOnSuccess
混淆,但与此类触发器相反,当发出 any 成功值(包括空 Mono
时,会触发 doOnNext
,这仍然有效。
Mono.just("Hello World")
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On next: Hello World
On success: Hello World
空单声道
记住,虽然 Mono
是空的 (Mono.empty()
),它仍然是触发 doOnNext
的有效响应,但不是 doOnSuccess
,一个空的 Mono
可以理解为有效响应,但不代表包含有用值的所需输出。它的工作原理与 Optional.empty()
相同。 Mono
成功但没有触发 doOnNext
的实际有用值,因为它根本不发出任何值。
Mono.empty()
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
Mono.just("Hello World")
.mapNotNull(s -> null)
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
两者的结果相同:
On success: null
错误的单声道
为了完整起见,与空 Mono
进行对比,错误不会触发 doOnNext
或 doOnSuccess
,而是触发 doOnError
:
Mono.error(new RuntimeException("Something wrong"))
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On error: java.lang.RuntimeException: Something wrong