在Reactor編程中有時候咱們須要對empty Mono<T>
作一些特定業務邏輯。下面看一段非reactor編程的代碼:html
public void oldCheck(Token token) { if (token == null) { // business logic return; } if (token.isExpired) { // business logic return; } // business logic return; }
若是讓你改爲reactor你也許會改爲這樣:java
public Mono<Void> badCheck(Mono<Token> tokenMono) { return tokenMono .flatMap(token -> { if (token == null) { // CAUTION: You will never be in here // business logic return Mono.empty(); } if (token.isExpired) { // business logic return Mono.empty(); } // business logic return Mono.empty(); }); }
上面的示例代碼裏的註釋已經寫了if (token == null) {}
的這個條件是永遠成立的,這是由於當Mono<Token>
是empty時,它是不會觸發flatMap
的。諸如flatMap
的絕大部分Operator都依賴於Publisher
(Mono
和Flux
都是Pubisher
)推送數據(詳情請看javadoc),若是Publisher
自己無數據可推送,那麼就不會觸發Operator。換句話說flatMap
內部是不可能獲得null的。react
那麼怎麼作才能夠?你能夠使用Java 8的Optional
來做爲中間值:編程
public Mono<Void> goodCheck(Mono<Token> tokenMono) { return tokenMono // Transform Mono<Token> to Mono<Optional<Token>>. // If Mono<Token> is empty, flatMap will not be triggered, // then we will get a empty Mono<Optional<Token>> .flatMap(token -> Mono.just(Optional.of(token))) // If Mono<Optional<Token>> is empty, provide an empty Optional<Token>, // then we will get a non-empty Mono<Optional<Token>> anyway .defaultIfEmpty(Optional.empty()) // Since Mono<Optional<Token>> is not empty, flatMap will always be triggered. .flatMap(tokenOptional -> { if (!tokenOptional.isPresent()) { // business logic return Mono.empty(); } Token token = tokenOptional.get(); if (token.isExpired) { // business logic return Mono.empty(); } // business logic return Mono.empty(); }); }
除了defaultIfEmpty
以外,Reactor還提供了switchIfEmpty
、repeatWhenEmpty
來處理empty Mono
/Flux
。api