问题
I have a method that try use WebClient to return a Mono
@GetMapping("getMatch")
public Mono<Object> getMatch(@RequestParam Long matchId) {
return WebClient.create(OpenDotaConstant.BASE_URL).get()
.uri("/matches/{matchId}", matchId)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(Object.class);
}
It can return result that I expected. Then I try to create another method to support List as params
@GetMapping("getMatches")
public Flux<Object> getMatches(@RequestParam String matchesId) {
List<Long> matchesList = JSON.parseArray(matchesId, Long.class);
return Flux.fromStream(matchesList.parallelStream().map(this::getMatch));
}
But this time return a weird result.
[
{
"scanAvailable": true
},
{
"scanAvailable": true
}
]
I'm new to reactive-programming, What is the correct way to combine Stream and Mono,and then convert to the Flux?
回答1:
Probably, what you need is the following:
@GetMapping("getMatches")
public Flux<Object> getMatches(@RequestParam String matchesId) {
List<Long> matchesList = JSON.parseArray(matchesId, Long.class);
return Flux.fromStream(matchesList.stream())
.flatMap(this::getMatch);
}
Instead of:
@GetMapping("getMatches")
public Flux<Object> getMatches(@RequestParam String matchesId) {
List<Long> matchesList = JSON.parseArray(matchesId, Long.class);
return Flux.fromStream(matchesList.parallelStream().map(this::getMatch));
}
Notes:
Basically, you expect
getMatches
endpoint to returnFlux<Object>
. However, as it is written - it actually returnsFlux<Mono<Object>>
, therefore you see the strange output. To getFlux<Object>
, I suggest, first, createFlux<Long>
that are match ids, and thenflatMap
the result of callinggetMatch
(that returnsMono<Object>
), this finally givesFlux<Object>
.Also, there is no need to use
parallelStream()
. Because you're already using reactor, everything will be performed concurrently on reactor scheduler.
来源:https://stackoverflow.com/questions/58153574/how-can-i-convert-a-stream-of-mono-to-flux