Search code examples
spring-webfluxreactor

Wait the end of a subscription loop before returning value


Im new to reactive programming paradigm. I have a simple question.

I have a list of elements, for each element i must do a REST call.

I must build a new list based on the response of these calls.

The problem is that my function returns value before the end of the loop... I don't know how to do ?

Here my piece of code :

TaeaUpdateRequestOutput putTaea(final String dossierId, final TaeaUpdateRequestInput input, final String token) {

    final TaeaUpdateRequestOutput output = new TaeaUpdateRequestOutput();

    input.getAdhesions().stream().forEach(adhesion -> {

        final Mono<TaeaFromMyMB> taeaResponse = doRest(adhesion, TaeaFromMyMB.class, url, token, dossierId);

        taeaResponse.subscribe(myMBTaea -> {
            final Taea taea = myMBTaea.fromTaeaFromMyMb(adhesion);
            output.getListeTaea().add(taea);
        });
    });
    //output is always empty due to async programming. How to wait the the end of the last iteration's subscription?
    return output;
}

Solution

  • You subscribed taeaResponsesbut you didn't wait result of the subscription.

    Try something like

        List<Taea> taeas = Flux.fromIterable(input.getAdhesions())
                .flatMap(adhesion -> doRest(adhesion, TaeaFromMyMB.class, url, token, dossierId)
                        .map(taeaFromMyMB -> taeaFromMyMB.fromTaeaFromMyMb(adhesion)))
                .collect(Collectors.toList())
                .subscribeOn(Schedulers.parallel())
                // wait result here
                .block();
    

    Then set it to the output.

    Keep in mind that block() waits indefinitely, so you can use reactor.core.publisher.Mono#block(java.time.Duration) to avoid it.