我正在使用Spring WebFlux进行一些异步API调用。问题是这些调用需要按顺序进行,因为每个调用都依赖于前一个调用。
- 呼叫C依赖于呼叫B
- 呼叫B依赖于呼叫A
最后,我需要所有调用(A、B和C)的值来创建响应DTO。
为了实现这一点,我使用嵌套的flatMaps,像这样:
public Flux<PersonDto> getPersons() {
return service.callA()
.flatMap(dtoCallA -> {
String name = dtoCallA.getName();
String addressId = dtoCallA.getAddressId();
service.callB(addressId)
.flatMap(dtoCallB -> {
String address = dtoCallB.getAddress();
String postalCodeId = dtoCallB.getPostalCodeId();
service.callC(postalCodeId)
.flatmap(dtoCallC -> {
String postalCode = dtoCallC.getPostalCode();
return PersonDto.builder()
.name(name)
.address(adress)
.postalCode(postalCode)
.build();
});
});
});
}
我如何改进这一点并保持单一责任原则?这些调用不能同时发生。我应该使用上下文还是zipWhen?
我不知道context
,但你能重写代码吗?
Flux<DtoA> dtoA = service.callA();
Flux<DtoB> dtoB = dtoA.flatMap(dtoCallA-> ... );
Flux<DtoC> dtoC = dtoB.flatMap(dtoCallB-> .... );
Flux<PersonDto> = dtoC.flatMap(dtoCallC-> ... );
我怀疑它将被编译/优化成相同的字节码。
编辑:
public class TuplePlay {
public static void main(String[] args) {
new TuplePlay().run();
}
@Data
@Builder
static class Person {
String a;
String b;
String c;
}
private void run() {
Mono<Tuple2<String, Person>> sar = sa.get().map(s1->Tuples.of(s1, Person.builder().a(s1).build()));
Mono<Tuple2<String, Person>> sbr = sar.flatMap(t->sb.apply(t.getT1()).map(s2->{t.getT2().setB(s2); return Tuples.of(s2, t.getT2());}));
Mono<Person> scr = sbr.flatMap(t->sc.apply(t.getT1()).map(s3->{t.getT2().setC(s3); return t.getT2();}));
scr.subscribe(System.out::println);
}
Supplier<Mono<String>> sa = () -> Mono.just("A");
Function<String, Mono<String>> sb = s->Mono.just("B of " + s);
Function<String, Mono<String>> sc = s->Mono.just("C of " + s);
}