WebFlux 映射的正确使用

Right using of mapping in WebFlux

public Mono<EmailDto> getEmail() {
Mono<EmailService> emailService = ReactiveSecurityContextHolder.getContext()
                    .map(securityContext -> (Principal) securityContext.getAuthentication().getPrincipal())
                    .map(principal -> emailServiceSelector.selectSuitable(principal.getInfo()));

return emailService.map(service -> service.findInfoByEmail(dto.getManagerEmail())) }

但是我用这个方法有问题,因为emailService.map(service -> service.findInfoByEmail(dto.getManagerEmail())) returns Mono<Mono<EmailDto>>findInfoByEmail(String email) 的实现是

public Mono<EmailDto> findInfoByEmail(String email) {
        return webClient.get()
                .uri(emailServiceProperties.getUrl(), email)
                .retrieve()
                .bodyToMono(EmailDto.class);
}

我的方法 returns Mono<EmailDto>,不是 Mono<Mono<EmailDto>>。 所以,我的问题是: 如何将Mono<Mono<EmailDto>>转换为Mono<EmailDto>?或者 mb 我完全错了,方法应该 return Mono<Mono<EmailDto>>?期待任何帮助。

平面图和地图之间存在 差异flatMap 应该用于 非阻塞 操作,或者简而言之 returns 支持 Mono,Flux 的任何东西。 map当你想对一个对象/数据进行固定时间的转换时应该使用。 同步完成的操作.

您的 findInfoByEmail 正在进行异步调用。

因此你应该使用:

return emailService.flatMap(service -> service.findInfoByEmail(dto.getManagerEmail())) }

来自官方doc

您做的一切都正确,但您需要使用 flatMap() 代替 map()。 map 用于将特定对象转换为其他对象,因为在您的情况下, flatMap() 用于将所有 1 到 N 对象转换为 Mono 。 所以你可以使用下面的代码片段:-

return emailService.flatMap(服务 -> service.findInfoByEmail(dto.getManagerEmail())) }