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

Mar*_*tin 0 java spring project-reactor spring-webflux

假设我有一个方法,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) 
}
Run Code Online (Sandbox Code Playgroud)

我想从该行传递一个结果:

userRepository.findUserByUsername(principal.getName())
Run Code Online (Sandbox Code Playgroud)

.doOnSuccess(song -> songRepository.findSongById(songId))
Run Code Online (Sandbox Code Playgroud)

到该行中的构建对象:

.doOnSuccess(vote -> voteRepository.add(Vote.builder().song(here result from findSongById).user(here result from findUserByUsername))
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ski 5

马丁,

首先,要知道.doOnXXX刚刚回调,这将在一定条件存档来执行。您应该避免将业务逻辑放入其中。

回到这个问题,我想到的第一个想法是从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
}
Run Code Online (Sandbox Code Playgroud)