1. 概述
在本簡短教程中,我們將探索 Spring 5 WebFlux 對象的各種監聽器。我們將比較 <em >doOnNext()</em > 和 <em >doOnSuccess()</em > 方法,並發現即使它們相似,對於空 <em >Mono</em > 對象,它們也表現出不同的行為。
2. doOnNext
Mono 的 doOnNext 允許我們附加一個監聽器,該監聽器將在數據發出時觸發。 對於本文中的代碼示例,我們將使用 PaymentService 類。 在這種情況下,我們將在 paymentMono 發出數據時調用 processPayment 方法,使用 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 也不會被觸發。 因此,如果我們使用 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
我們可以使用 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,上述代碼將使用 Payment 為 null 調用 processPayment 方法:
Test
void givenAnEmptyMono_whenCallingServiceOnSuccess_thenCallServiceWithNull() {
Mono<Payment> emptyMono = Mono.empty();
emptyMono.doOnSuccess(paymentService::processPayment)
.block();
verify(paymentService).processPayment(null);
}4. 結論
在本文中,我們學習了 <em>Mono</em> 的 <em>doOnNext</em> 和 <em>doOnSuccess</em> 監聽器之間的區別。我們瞭解到,如果希望對接收到的數據做出反應,可以使用 <em>doOnNext</em>。另一方面,如果希望方法調用在 <em>Mono</em> 成功完成時發生,無論它是否發出數據,都應該使用 <em>doOnSuccess</em>。