概述
WebFlux响应式编程Mono监听器doOnNext和doOnSuccess的作用很相似,都可以对收到的数据做出反应,但对于空Mono,两者的行为却完全不同。
doOnNext
Mono允许我们附加一个监听器doOnNext,该监听器将在数据发出时触发:
@Test
void givenAPaymentMono_whenCallingServiceOnNext_thenCallServiceWithPayment() {
Payment paymentOf100 = new Payment(100);
Mono<Payment> paymentMono = Mono.just(paymentOf100);
paymentMono.doOnNext(paymentService::processPayment).block();
verify(paymentService).processPayment(paymentOf100);
}
但是如果是空的Mono,不会发出任何数据,并且不会触发doOnNext:
@Test
void givenAnEmptyMono_whenCallingServiceOnNext_thenDoNotCallService() {
Mono<Payment> emptyMono = Mono.empty();
emptyMono.doOnNext(paymentService::processPayment).block();
verify(paymentService, never()).processPayment(any());
}
doOnSuccess
我们可以使用doOnSuccess附加一个侦听器,当Mono成功完成时将触发该侦听器。这次使用doOnSuccess重复测试:
@Test
void givenAPaymentMono_whenCallingServiceOnSuccess_thenCallServiceWithPayment() {
Payment paymentOf100 = new Payment(100);
Mono<Payment> paymentMono = Mono.just(paymentOf100);
paymentMono.doOnSuccess(paymentService::processPayment).block();
verify(paymentService).processPayment(paymentOf100);
}
但是即使没有发出数据,Mono也被认为是成功完成的。因此,对于空的Mono,上面的代码将doOnSuccess仍然会被触发并传入空数据:
@Test
void givenAnEmptyMono_whenCallingServiceOnSuccess_thenCallServiceWithNull() {
Mono<Payment> emptyMono = Mono.empty();
emptyMono.doOnSuccess(paymentService::processPayment).block();
verify(paymentService).processPayment(null);
}
结论
通过测试用例对比了Mono的doOnNext和doOnSuccess监听器之间的区别:
- 如果想对收到的数据做出反应,可以使用doOnNext;
- 如果希望Mono成功完成时进行方法调用,无论Mono是否发出数据,都应该使用doOnSuccess。