如何将Mono流转换为Flux

时间:2019-09-29 08:30:35

标签: spring-webflux

我有一个方法尝试使用WebClient返回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);

    }

它可以返回我期望的结果。 然后我尝试创建另一种方法来支持List作为参数

    @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));
    }

但是这次返回一个奇怪的结果。

[
    {
        "scanAvailable": true
    },
    {
        "scanAvailable": true
    }
]

我是反应式编程的新手,将Stream和Mono组合然后转换为Flux的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

可能,您需要的是以下内容:

@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);
}

代替:

@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));
}

注意:

  • 基本上,您希望getMatches端点返回Flux<Object>。但是,在编写时-它实际上返回Flux<Mono<Object>>,因此您会看到奇怪的输出。为了获得Flux<Object>,我建议首先创建具有匹配ID的Flux<Long>,然后创建flatMap调用getMatch的结果(返回Mono<Object>),最终得到Flux<Object>

  • 此外,也无需使用parallelStream()。因为您已经在使用反应堆,所以所有操作都将在反应堆调度程序上同时执行。