Молния три разных моно разного типа - PullRequest
1 голос
/ 18 октября 2019

Я начал новый проект, используя Spring Webflux, и я довольно новичок в этой парадигме реактивного кодирования. Поэтому заранее извиняюсь за вопросы, как у новичков.

Мой метод контроллера возвращает ответ как Mono<ResponseEntity<String>>, и у меня есть три разные службы для вызова, откуда я получаю три разных объекта Mono, как этот -

Mono<CustomObject> customMono = serivce1.method();
Mono<Boolean> booleanMono = service2.method();
Mono<String> stringMono = service3.method();

Таким образом, чтобы подготовить ответ (Mono<ResponseEntity<String>>), мне нужно сделать что-то вроде этого -

Mono.zip(customMono, booleanMono, stringMono, (customData, booleanData, stringData) -> {
------
return Mono.just(ResponseEntity.ok().body("-----"));
});

Проблема в том, что нет такого zip метода, чтобы взять 3Mono и функция в качестве параметров. Я уже нашел это - https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#zip-reactor.core.publisher.Mono-reactor.core.publisher.Mono-java.util.function.BiFunction-

, но это не соответствует моему требованию. Поэтому проблемы, с которыми я сталкиваюсь

  • Я не могу использовать Mono.mergeWith или Mono.concaWith метод, потому что мой объект Mono другого типа.
  • Я могу использовать FlatMap / map для каждого Mono и создать цепочку. Но я хочу, чтобы service2 вызывался параллельно в отдельном потоке, поскольку он не зависит от вызова service1. Но вызов service3 зависит от ответа service1.

Итак, что мне нужно сделать:

  • сначала выполнить вызов service1
  • выполнить вызов service2отдельно в другом потоке
  • сделать вызов service3, который зависит от данных вызова service1
  • , сгенерировав окончательный объект ответа (Mono<ResponseEntity<String>>), используя данные из всего вызова службы.

Заранее спасибо. Как новичок, любые предложения приветствуются.

Ответы [ 2 ]

3 голосов
/ 18 октября 2019

Для вашего конкретного состояния вам нужно Mono.zipWhen(), что гарантирует, что ваш 3-й сервисный вызов будет иметь данные, необходимые для ответа на сервисный вызов 1

Mono.zip(monoResponse1,monoResponse2).zipWhen(data ->serviceCall3(data.getT1())).flatMap(response ->{
    response.getT1().getT1();//response from mono1
    response.getT1().getT2();//response from mono 2
    response.getT2();//response from mono 3
    return {create your mono response here};
} );
2 голосов
/ 18 октября 2019

Всякий раз, когда вы заархивируете два моно, тогда третий параметр будет BiFunction, но с тремя параметрами он вернет flatmap из tuple, тогда в кортеже вы получите ответ других моно. Вам необходимо изменить код следующим образом.

Mono.zip(customMono, booleanMono, stringMono).flatMap(data->{
 data.getT1();
 data.getT2();
 data.getT3();
 return Mono.just(<your_response_object>);
});

Теперь, что будет типом возврата getT1(), getT2() и getT3()?

Очевидно, это будет зависеть от того, что вернет ваш Zip Mono .

Надеюсь, что это поможет вам.

...