简体   繁体   English

如何等到多个 WebClient Flux 请求完成?

[英]How can I wait until multiple WebClient Flux requests are finished?

I want to:我想要:

  1. subscribe to multiple endpoints returning Flux and output the messages I receive.订阅多个端点返回 Flux 和 output 我收到的消息。
  2. wait until all messages have been output from all endpoints before continuing.等到所有端点的所有消息都是 output 后再继续。
  3. avoid processing messages from multiple endpoints "together" (eg Flux.zip) because the endpoints will return an uneven number of messages and are not logically connected to each other避免“一起”处理来自多个端点(例如 Flux.zip)的消息,因为端点将返回奇数数量的消息并且彼此没有逻辑连接
  4. block forever if one or more endpoints generate an infinite number of messages如果一个或多个端点生成无限数量的消息,则永远阻塞

The following code satisfies 1 and 3 but not 2 and 4:以下代码满足 1 和 3,但不满足 2 和 4:

        Stream.of("http://service1.com", "http://service2.com", "http://service3.com")
                .forEach(service -> {
                    webClient.get()
                            .retrieve()
                            .bodyToFlux(String.class)
                            .map(message -> service + ": " + message)
                            .subscribe(System.out::println);
                });

        System.out.println("Received all messages");

The line "Received all messages" should not be printed until all endpoints have finished.在所有端点完成之前,不应打印“已接收所有消息”行。 However, because subscribe is asynchronous, that line is instead printed almost immediately and my application continues instead of waiting.但是,因为subscribe是异步的,所以该行几乎立即打印出来,我的应用程序继续而不是等待。

What should I do differently?我应该怎么做?

I believe the following code snippet achieves 3 out of 4 points in your question though I do not feel like I fully understand the 3rd requirement.我相信以下代码片段在您的问题中达到了 4 分中的 3 分,尽管我觉得我并不完全理解第三个要求。 Let me if this example meets what is needed and if not, what is missing.让我看看这个例子是否满足需要,如果不满足,那么缺少什么。

        Flux.just("http://service1.com", "http://service2.com", "http://service3.com")
            .flatMap(url -> webClient.get()
                    .uri(url)
                    .retrieve()
                    .bodyToFlux(String.class)
                    .map(body -> url + ":" + body)
            )
            .collectList()
            .doOnNext(list -> LOG.info("Received all messages"))
            .subscribe(list -> LOG.info("" + list));

flatMap is one way to merge fluxes together but you can also use Flux.merge flatMap 是将通量合并在一起的一种方法,但您也可以使用 Flux.merge

    List<Flux<String>> individualResults =
        Stream.of("http://service1.com", "http://service2.com", "http://service3.com")
            .map(
                service ->
                    webClient //
                        .get()
                        .retrieve()
                        .bodyToFlux(String.class))
            .collect(toList());
    Flux<String> mergedResults = Flux.merge(individualResults);  // Will not complete until all individual Fluxes have completed.
    mergedResults //
        .doOnNext(System.out::println)
        .then()
        .block(); // block this thread until mergedResults completes
    System.out.println("Received all messages");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM