Comparison Between Mono’s doOnNext() and doOnSuccess() – Mono’的doOnNext()和doOnSuccess()之间的比较

最后修改: 2022年 10月 11日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we’ll explore various listeners of the Mono object from Spring 5 WebFlux. We’ll compare the doOnNext() and doOnSuccess() methods and discover that, even though they’re similar, they behave differently for empty Monos.

在这个简短的教程中,我们将探讨来自Spring 5 WebFlux的Mono对象的各种监听者。我们将比较doOnNext()doOnSuccess()方法,并发现尽管它们很相似,但对于空的Monos,它们的行为是不同的。

2. doOnNext

2.doOnNext

Mono‘s doOnNext() allows us to attach a listener that will be triggered when the data is emitted. For the code examples in this article, we’ll use the PaymentService class. In this case, we’ll call the processPayment method only when the paymentMono emits the data, using doOnNext():

MonodoOnNext()允许我们附加一个监听器,该监听器将在数据被发射时被触发。在本文的代码示例中,我们将使用PaymentService类。在这种情况下,我们将只在paymentMono发射数据时,使用doOnNext()调用processPayment方法。

@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);
}

However, an empty Mono will not emit any data, and doOnNext will not be triggered. Consequently, if we repeat the test using Mono.empty(), the processPayment method should no longer be called:

然而,一个空的Mono将不会发出任何数据,并且doOnNext将不会被触发。因此,如果我们使用Mono.empty()重复测试,processPayment方法不应该再被调用。

@Test
void givenAnEmptyMono_whenCallingServiceOnNext_thenDoNotCallService() {
    Mono<Payment> emptyMono = Mono.empty();

    emptyMono.doOnNext(paymentService::processPayment)
        .block();

    verify(paymentService, never()).processPayment(any());
}

3. doOnSuccess

3.doOnSuccess

We can use doOnSuccess to attach a listener that will be triggered when the Mono completes successfully. Let’s repeat the test, but using doOnSuccess this time:

我们可以使用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);
}

Though, we should note that a Mono is considered to be completed successfully even if no data is emitted. As a result, for an empty Mono, the code above will call the processPayment method with a null Payment:

不过,我们应该注意到,即使没有数据发射,Mono也会被认为是成功完成。因此,对于一个空的Mono,上面的代码将以null Payment调用processPayment方法。

Test
void givenAnEmptyMono_whenCallingServiceOnSuccess_thenCallServiceWithNull() {
    Mono<Payment> emptyMono = Mono.empty();

    emptyMono.doOnSuccess(paymentService::processPayment)
        .block();

    verify(paymentService).processPayment(null);
}

4. Conclusion

4.总结

In this short article, we learned the difference between a Mono‘s doOnNext and doOnSuccess listeners. We saw that we can use doOnNext if we want to react to the data received. On the other hand, we should use doOnSuccess if we want the method call to happen when the Mono completes successfully, regardless of whether it emits data or not.

在这篇短文中,我们了解了MonodoOnNextdoOnSuccess监听器之间的区别。我们看到,如果我们想对收到的数据做出反应,我们可以使用doOnNext。另一方面,如果我们想让方法调用在Mono成功完成时发生,不管它是否发射了数据,我们都应该使用doOnSuccess

As always, code from this article can be found over on GitHub.

一如既往,本文的代码可以在GitHub上找到over