![](/img/trans.png)
[英]How to iterate over Flux and use result from another Mono to filter the Flux
[英]How to iterate Flux and mix with Mono
我有一個用例,當我應該向用戶發送電子郵件時。 首先,我創建電子郵件正文。
Mono<String> emailBody = ...cache();
然后,我選擇用戶並將電子郵件發送給他們:
Flux.fromIterable(userRepository.findAllByRole(Role.USER))
.map(User::getEmail)
.doOnNext(email -> sendEmail(email, emailBody.block(), massSendingSubject))
.subscribe();
我不喜歡的
此代碼示例中有幾個問題。 我假設這是一個響應式Web應用程序。
首先,不清楚如何創建電子郵件正文。 您是從數據庫還是遠程服務中獲取東西? 如果它主要是受CPU限制的(而不是I / O),則不需要將其包裝為響應類型。 現在,如果它應該在Publisher
包裝並且所有用戶的電子郵件內容都相同,則使用cache
運算符不是一個壞選擇。
另外, Flux.fromIterable(userRepository.findAllByRole(Role.USER))
建議您從響應上下文中調用阻塞存儲庫。
永遠不要在doOn***
運算符中執行繁重的I / O操作。 這些是為測井或輕微副作用而設計的。 您需要在其上使用.block()
的事實是您將阻塞整個反應式管道的另一個線索。
最后一個:您不應在Web應用程序中的任何地方調用subscribe
。 如果這綁定到HTTP請求,則基本上是在觸發反應式管道,而不能保證資源或完成。 調用subscribe
會觸發管道,但不會等到完成(此方法返回Disposable
)。
更為“典型”的示例如下所示:
Flux<User> users = userRepository.findAllByRole(Role.USER);
String emailBody = emailContentGenerator.createEmail();
// sendEmail() should return Mono<Void> to signal when the send operation is done
Mono<Void> sendEmailsOperation = users
.flatMap(user -> sendEmail(user.getEmail(), emailBody, subject))
.then();
// something else should subscribe to that reactive type,
// you could plug that as a return value of a Controller for example
如果您因阻塞組件而陷入困境(例如sendEmail
一個),則應在特定的調度程序上調度這些阻塞操作,以避免阻塞整個響應式管道。 為此,請查看反應堆參考文檔上的 “ 計划程序”部分 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.