Возможно, описанная выше проблема не была четко передана, поэтому я просто перефразирую ее и затем опишу свое решение. Надеюсь, это поможет кому-то!
Также важное примечание: это решение сделано в Java Spring с использованием WebClient для выполнения асинхронных запросов на стороне клиента к удаленному серверу.
В зависимости от количества URN, Я должен сделать несколько асинхронных HTTP-запросов, каждый из которых представлен Mono.
Допустим, есть функция, которая принимает ArrayList конечных точек HTTP и возвращает ArrayList типа MyObject. Я хочу, чтобы эта функция принимала эти конечные точки и выполняла соответствующее количество HTTP-запросов с использованием Monos, которые будут заполнять это количество объектов POJO MyObject (простых старых Java объектов), однако, поскольку число Monos будет отличаться в зависимости от количества конечных точек Я не могу явно определить каждый моно. Я использую Monos, чтобы позволить мне выполнять эти запросы параллельно или одновременно, а не последовательно по одному, и я хочу получать уведомления, когда все мои Monos завершены и могут создавать экземпляры MyObject.
Поскольку я хочу, чтобы программа могла перемещаться на другие части программы при выполнении этого метода и выполнении всех запросов, как мне go сообщить о сжатии различных Monos и возврате результата для единственного объединенного потока, когда он завершится?
Решением для организации набора непредсказуемых моносов является сохранение итерируемого монослоя и слияние его в поток, который затем буферизуется и блокируется для создайте Java объекты!
(Важно понять, что такое Monos и Flux, чтобы полностью понять это решение)
public Mono<MyObject> getOneObject(String endpoint) {
return webClient.get()
.uri(endpoint)
.retrieve()
.bodyToMono(MyObject.class)
}
Эта функция выше извлекает один объект на основе одного конечная точка. Теперь давайте создадим Iterable из Monos на основе заданного списка конечных точек.
public Iterable<Mono<MyObject>> getMultipleObjects(ArrayList<String> endpoints) {
ArrayList<Mono<MyObject>> monos = new ArrayList<Mono<MyObject>> ();
for (String endpoint: endpoints) {
monos.add(getOneObject(endpoint));
}
return monos;
}
Эта функция возвращает ArrayList (приведенный к Iterable в операторе return), который заполняется путем перебора списка конечных точек. Теперь давайте объединяем повторяющиеся моно в единый поток!
public Flux<MyObject> mergeMultipleMonos(Iterable<Mono<MyObject>> multipleMonos) {
return Flux.merge(multipleMonos);
}
Теперь все, что вам нужно сделать, это создать буфер и заблокировать поток для создания ArrayList объектов!
public ArrayList<MyObject> listOfObjects(Flux<MyObject> fluxOfObjects) {
return fluxOfObjects.buffer().blockLast();
}
Flux.buffer () соберет все входящие значения в list, и Flux.blockLast () подпишется на этот поток и будет блокироваться на неопределенный срок, пока восходящий поток не сообщит свое последнее значение или не завершится.
И вот как непредсказуемое число Monos, в данном случае представляющее асинхронные клиентские веб-запросы HTTP, может быть объединено в единый поток, который также будет заполнять все значения, когда каждый запрос будет возвращен!