如何将上一步的 Mono<> 结果传递给下一个 doOnSuccess() 方法

How to pass Mono<> result from previous step to the next doOnSuccess() method

假设我有一个方法 addVoteToSong 比如:

public Mono<Map<Song, VoteKind>> addVoteToSong(Principal principal, String songId, VoteKind voteKind) {
        return
            userRepository.findUserByUsername(principal.getName())
            .doOnSuccess(song -> songRepository.findSongById(songId))
            .doOnSuccess(vote -> voteRepository.add(Vote.builder().song()))
            .//(the rest of the code) 
}

我想传递以下行的结果:

userRepository.findUserByUsername(principal.getName())

.doOnSuccess(song -> songRepository.findSongById(songId))

到行中的构建对象:

.doOnSuccess(vote -> voteRepository.add(Vote.builder().song(here result from findSongById).user(here result from findUserByUsername))

问题来了,是否可以在下一个doOnSuccess方法中重用之前的API调用结果,或者我应该同时拆分find API调用,放弃关于 Reactor 的级联操作?在互联网上,我找到了使用单个 save 方法的示例,而不是基于反应流的间接结果,这就是出现问题的原因。我将不胜感激有关如何实现目标的建议。

马丁,

首先,请注意 .doOnXXXjust callbacks 将在某些存档条件下执行。您应该避免将业务逻辑放入其中。

回到问题,我想到的第一个想法是受益于 zip 运算符。因此,您必须放置 2 个发布者 .findUserByUsername.findSongById,然后使用 BiFunction 组合结果。所以你可以尝试以下方法:

public Mono<Map<Song, VoteKind>> addVoteToSong(Principal principal, String songId, VoteKind voteKind) {
    return Mono
            .zip(
                    userRepository.findUserByUsername(principal.getName()),
                    songRepository.findSongById(songId),
                    (user, song) -> voteRepository.add(Vote.builder().song(song).user(user).build())
            )
            .flatMap(Function.identity())
            // your code is here
}