Java 将调用weclient的传统循环转换为非阻塞方式

Java 将调用weclient的传统循环转换为非阻塞方式,java,spring,webclient,spring-webflux,project-reactor,Java,Spring,Webclient,Spring Webflux,Project Reactor,我是反应式编程的新手,我想把下面的代码转换成非阻塞的方式 为了简单起见,我根据原始代码创建了一个示例伪代码。任何帮助都将不胜感激 public Mono<Response> getResponse(List<Provider> providers) { for (Provider provider : providers) { Response response = provider.invokeHttpCall().block();

我是反应式编程的新手,我想把下面的代码转换成非阻塞的方式

为了简单起见,我根据原始代码创建了一个示例伪代码。任何帮助都将不胜感激

 public Mono<Response> getResponse(List<Provider> providers) {

    for (Provider provider : providers) {
        Response response = provider.invokeHttpCall().block();

        if(response.getMessage() == "Success") {
            return Mono.just(response);
        }

        continue;
    }

    return Mono.empty();
}

我尝试了几种策略来实现这一点,但仍然没有成功。要么调用所有提供程序,要么我需要阻止webclient线程。

反应式是一种流。请将其视为一个流,并对其进行反应性编程

我给你这样的代码

  • 首先,使用
    Flux.fromIterable()
    从列表创建流量流
  • 接下来,使用
    flatmap()
  • 使用方法
    filterWhen()
    和Lambda获得“Success”响应,只获得第一个“Success”元素。见api文件
  • 最后,只需使用
    Mono.from()
    包装
    Flux
    ,然后返回
    Mono
    类型
  • 公共Mono getResponse(列表提供程序){ 返回Mono.from(通量.fromIterable(提供程序) .flatmap(提供程序-> Mono.defer(()->provider.invokeHttpCall()) .filterWhen(response->response.getMessage()=“成功”); }
    如果要查看结果和
    println()
    。 只需使用
    .subscribe()
    方法来执行它

    getResponse.subscribe(System.out::println);
    
    Flux.fromIterable(提供程序)
    .concatMap(Provider::invokeHttpCall)//确保按顺序调用提供程序
    .filter(response->response.getMessage().equals(“成功”))
    .next()
    
    感谢您的响应。上面代码中的问题是,所有提供程序都将被调用。我只想在当前提供程序响应在指定条件下不合格时继续下一次迭代。只需添加
    provider.invokeHttpCall()
    是一个webclient调用。它将使用另一个线程来执行http调用。Hi@dyy.alex。您的代码正在工作。如果我在将其标记为已接受的答案之前询问,是否有一个不阻止webclient线程的可能解决方案?@JeromeyanVillamor,当然有。但是首先,您需要覆盖您的syn方法提供程序。invokeHttpCall()作为异步方法。其次,您需要使用reactor包装异步方法,以便返回Mono或Flux类型。如果您认为我的解决方案很好,我很乐意接受upvote:)
        @Override
        public Mono<Response> invokeHttpCall(){
            WebClient webClient = WebClient.create();
            
            
            return webClient.post()
                    .uri("/provider").accept(MediaType.APPLICATION_JSON)
                    .retrieve()
                    .bodyToMono(Response.class);
        }