我试图同时进行 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 的新手。预先感谢。
您可以使用
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;
});
我的解决方案与
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);
}
每当到达第 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();