如何压缩超过 8 种不同类型的单声道

问题描述 投票:0回答:3

我试图同时进行 9 个 api 调用。所有这些调用都会返回不同的响应对象。在此之前,我们有 8 个 api 调用,由于这些 mono 是不同的类型,我使用了 Mono.zip,如下所示。

Mono<ResponseEntity<Service1Response>> monoService1 = callService1();
Mono<ResponseEntity<Service2Response>> monoService2 = callService2();
...
Mono<ResponseEntity<Service3Response>> monoService7 = callService7();
Mono<ResponseEntity<Service4Response>> monoService8 = callService8();

MixResponse mix = Mono.zip(monoService1, monoService2, monoService3, monoService4, monoService5, monoService6, monoService7, monoService8).flatMap(response -> {
  MixResponse mixResp = new MixResponse();
  mixResp.setResponse1(response.getT1().getBody());
  mixResp.setResponse2(response.getT2().getBody());
  mixResp.setResponse3(response.getT3().getBody());
  mixResp.setResponse4(response.getT4().getBody());
  mixResp.setResponse5(response.getT5().getBody());
  mixResp.setResponse6(response.getT6().getBody());
  mixResp.setResponse7(response.getT7().getBody());
  mixResp.setResponse8(response.getT8().getBody());
  return Mono.just(mixResp);
})).block();

但现在我们多了一项服务,而 Mono.zip 最多只支持 8 个单声道。除了 Mono.zip 之外,还有什么我可以在我的情况下使用的吗?抱歉,如果这个问题看起来很愚蠢。我是 spring-webflux 的新手。预先感谢。

java spring spring-webflux project-reactor
3个回答
2
投票

您可以使用

Mono.zip
Iterable
作为参数和组合器函数来组合结果并转换为特定类型:

<R> Mono<R> zip(final Iterable<? extends Mono<?>> monos, Function<? super Object[], ? extends R> combinator)


List<Mono<? extends ResponseEntity<?>>> requests = List.of(
        monoService1, 
        monoService2, 
        monoService3, 
        monoService4
);

Mono.zip(requests, responses -> {
    MixResponse mixResp = new MixResponse();
    mixResp.setResponse1(((ResponseEntity<Service1Response>) responses[0]).getBody());
    mixResp.setResponse2(((ResponseEntity<Service2Response>) responses[1]).getBody());
    mixResp.setResponse3(((ResponseEntity<Service3Response>) responses[2]).getBody());
    mixResp.setResponse4(((ResponseEntity<Service4Response>) responses[3]).getBody());
    return mixResp;
});

1
投票

我的解决方案与

TupleUtils.function
类似:

Mono.zip(
    monoService1,
    monoService2,
    monoService3,
    monoService4,
    monoService5,
    monoService6,
    monoService7,
    monoService8 
).zipWith(Mono.zip( // the max number of Mono.zip which can return a tuple is 8, therefore we had to split into two chunks
    monoService9,
    monoService10 
), BigTuple::new
).map(bigFunction((res1, res2, res3, res4, res4, res5, res6, res7, res8, res9, res10) ->
    // resX are all preserving their types and all named
));

为此,您必须实现您的

BigTuple
bigFunction
。不幸的是,这都是样板代码。

import java.util.function.Function;
import lombok.AllArgsConstructor;
import lombok.Value;

public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> Function<BigTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, R> bigFunction(
        BigFunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> function) {
    return tuple -> function.apply(tuple.getT1(), tuple.getT2(), tuple.getT3(), tuple.getT4(), tuple.getT5(), tuple.getT6(),
            tuple.getT7(), tuple.getT8(), tuple.getT9(), tuple.getT10());
}

@Value
@AllArgsConstructor
private static class BigTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>  {
    T1 t1;
    T2 t2;
    T3 t3;
    T4 t4;
    T5 t5;
    T6 t6;
    T7 t7;
    T8 t8;
    T9 t9;
    T10 t10;

    BigTuple(Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> objects1, Tuple2<T9, T10> objects2) {
        this(objects1.getT1(), objects1.getT2(), objects1.getT3(), objects1.getT4(), objects1.getT5(),
                objects1.getT6(), objects1.getT7(), objects1.getT8(), objects2.getT1(), objects2.getT2());
    }
}

private interface BigFunction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> {
    R apply(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10);
}

0
投票

每当到达第 8 个参数时,您就可以使用嵌套的

Mono.zip

var results = Mono.zip(
  call1(),
  call2(),
  call3(),
  call4(),
  call5(),
  call6(),
  call7(),
  Mono.zip(
    call8(),
    call9(),
    call10()
  )
).block();

var result1 = results.getT1();
var result2 = results.getT2();
var result3 = results.getT3();
var result4 = results.getT4();
var result5 = results.getT5();
var result6 = results.getT6();
var result7 = results.getT7();
var result8 = results.getT8().getT1();
var result9 = results.getT8().getT2();
var result10 = results.getT8().getT3();
© www.soinside.com 2019 - 2024. All rights reserved.