何についてか
の続編でFluxについても書いておきます。
結論
Monoと同じくmapを使ってもOK。やはりreturn形式は"Mono<String>"であること。
@GetMapping("/hello")
public Mono<String> hello(Model model) {
Flux<DataDTO> dataMono = dataService.getData();
return dataMono.collectList().map(data ->
model.addAttribute("data", data)).then(Mono.just("index"));
}
- .collectList()はMono>を返してきます。つけ忘れると最後のdataしか処理されなかったです。さらに注意したいのは全てのリストの取得が終わるまで続けるので、out of memoryで落ちるまで終わらないらしいです。
- Monoの時と違ってdataの取得に時間がかかり非同期なのでthymeleaf側でnullとして判断されてしまう可能性が高いので、必ず処理が終わってからThymeleafに渡すために、thenをつかっています。
方法2
@GetMapping("/hello")
public Mono<String> hello(Model model) {
Flux<DataDTO> dataMono = dataService.getData();
return dataMono.collectList().doOnNext(data ->
model.addAttribute("data", data)).then(Mono.just("index"));
}
確実にdataが利用されている状態で処理したいのでdoOnNextを使った方がよさそうです。
他に試したこと
@GetMapping("/hello")
public String hello(Model model) {
Flux<DataDTO> dataMono = dataService.getData();
dataMono.collectList().subscribe(data ->
model.addAttribute("data", data));
return "index";
}
・やはり処理が非同期でおこなわれているためdataはnullでした
まとめ
MonoもFluxもその特徴である非同期処理のため、そのデータが処理する時に必ず存在しているかどうかを確認することが重要なポイントの一つのようです。
Fluxで受けたdataも最終的にはMonoにすることでThymeleafと会話することができました。
参考資料
Flux vs Mono
https://www.geeksforgeeks.org/difference-between-mono-and-flux-in-spring-webflux/
Class Flux
https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#map-java.util.function.Function-