簡體   English   中英

如何迭代Flux並與Mono混合

[英]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();

我不喜歡的

  1. 如果不使用cache()方法,則emailBody Mono將在每個迭代步驟中進行計算。
  2. 為了獲得emailBody的值,我使用了emailBody.block(),但也許有一種反應性的方法,而不是在Flux流中調用塊方法?

此代碼示例中有幾個問題。 我假設這是一個響應式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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM