我正在使用spring webflux来使用另一个服务,并尝试将结果汇总到不同输入组合的列表中。
但是遇到了我无法订阅并将结果转换为列表的问题


此方法将获取一个Map并遍历该Map并通过不同的输入组合调用另一个服务。
但是无法在getAPrice()中完成我想要的事情:(

输入:

 public Mono<List<APrice>> getAPrice() {
        return
                Mono.create(monoSink ->{
                     getActiveMonths()
                            .entrySet().stream()
                            .flatMap(e->getContractPrice(e.getKey(),e.getValue())
                            /* stuck here, don't have any idea how to subccribe and get the AP Object and collect it as a list */
                });
    }


输出:

expected : List[APrice]

上面的getAPrice()调用下面的方法,该方法可以正常工作并返回有效输入组合的数据

输入:

 /*Method is Working fine and returns a Mono<APrice> for the right input combination */
public Mono<APrice> getContractPrice(String key, String value){
    return Mono.create(monoSink ->{
        acServiceWebClient.getPrice(key,value)
                .subscribe(aPrice ->  monoSink.success(aPrice),
                        error->{
                            monoSink.error(error);
                        });
    });
}


输出:

{
"id": 11,
"curveName": "NT",
"Month": "Mar 2010",
"price": 160.17,
"status": "ACTIVE"
}



    private Map<String,String> getActiveMonths()
    {
        Map hm = new HashMap();
        hm.put("key1","value1")
        hm.put("key2","value2")
        return hm;
    }


期待获得一些建议,以更好的方式完成getAPrice(),以防我采用错误的方法纠正我。谢谢

最佳答案

您实际上并不需要MonoSink做您的工作。您可以做的是从Flux getActiveMonths创建一个entrySet,然后用该getActivePriceentrySetkey调用方法value。因此,您的getAPrice实际上应该看起来像

public Mono<List<APrice>> getAPrice() {

    return Flux.fromIterable(getActiveMonths().entrySet())
        .flatMap(entry -> getContractPrice(entry.getKey(), entry.getValue())).collectList();
}


在这里简单地创建Flux有两个原因。


您没有理由以编程方式创建序列(MonoSinkFluxSink主要用于此序列)。您的数据已经存在,您只需要使用它就可以进行任何操作。
实际上,您有一个集合,并且想要使用它的每个条目,这使其成为用于Flux(0-n个元素)而不是Mono(0-1个元素)的很好的候选对象。


请参考此Project Reactor官方文档,该文档更加清晰并证明了我的观点。

如果getContractPrice返回Mono<List<APrice>>?这是getAPrice的外观

public Mono<List<APrice>> getAPrice() {

    return Flux.fromIterable(getActiveMonths().entrySet())
        .flatMap(entry -> getContractPrice(entry.getKey(), entry.getValue()))
        .flatMapIterable(aPrices -> aPrices).collectList();
}

09-10 23:45