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

huangapple go评论73阅读模式
英文:

Convert traditional loop of invoking weclient into non blocking way

问题

我对响应式编程还不熟悉,我想将以下代码转换为非阻塞方式。

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

public Mono<Response> getResponse(List<Provider> providers) {
    return Flux.fromIterable(providers)
            .flatMap(provider -> provider.invokeHttpCall()
                    .filter(response -> response.getMessage().equals("Success"))
                    .switchIfEmpty(Mono.defer(() -> Mono.empty())))
            .next();
}

provider.invokeHttpCall() 方法

@Override
public Mono<Response> invokeHttpCall(){
    WebClient webClient = WebClient.create();
    
    return webClient.post()
            .uri("/provider").accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .bodyToMono(Response.class);
}

我尝试了几种策略来实现这个,但仍然没有成功。要么会调用所有的提供者,要么我需要阻塞 Web 客户端线程。

英文:

I am new to reactive programming and I want to transform the following code into non blocking way.

For the sake of simplicity, I created a sample pseudo code based from my original code. Any help will be appreciated.

 public Mono&lt;Response&gt; getResponse(List&lt;Provider&gt; providers) {

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

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

        continue;
    }

    return Mono.empty();
}

provider.invokeHttpCall() method

    @Override
    public Mono&lt;Response&gt; invokeHttpCall(){
        WebClient webClient = WebClient.create();
        
        
        return webClient.post()
                .uri(&quot;/provider&quot;).accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(Response.class);
    }

I tried several tactics to implement this, but still no luck. Either all providers are invoked or I need to block the webclient thread.

答案1

得分: 0

reactive 是一种流(Stream)类型。请将其视为流(Stream)并以响应式方式编程。

我为您提供以下代码:

  1. 首先,使用 Flux.fromIterable() 从列表创建一个 Flux 流。
  2. 接下来,使用 flatmap() 和 Lambda 函数将 invoke 发送到另一个新线程。
  3. 使用 filterWhen() 方法和 Lambda 表达式来获取 "Success" 响应并仅获取第一个 "Success" 元素。请参阅 filterwhen API 文档。
  4. 最后,只需使用 Mono.from() 包装 Flux,然后返回 Mono 类型。
public Mono<Response> getResponse(List<Provider> providers) {

    return Mono.from(Flux.fromIterable(providers)
                .flatMap(provider -> 
                    Mono.defer(() -> provider.invokeHttpCall())
                .filterWhen(response -> response.getMessage().equals("Success")));
}

如果您想要查看结果并使用 println() 打印出来,请使用 .subscribe() 方法来执行它。

getResponse.subscribe(System.out::println);
英文:

reactive is a kind of Stream. Please think it as a Stream and program it reactively.

I give you such followed code.

  1. Firstly, use Flux.fromIterable() to create a flux stream from a List.
  2. Next, use flatmap() and Lambda fuction to emit the invoke into another new thread.
  3. use method filterWhen() and Lambda to get the "Success" response and just get the first "Success" elements. See filterwhen api Doc.
  4. Finally, just use Mono.from() to wrap the Flux and then return the Mono type.
public Mono&lt;Response&gt; getResponse(List&lt;Provider&gt; providers) {

    return Mono.from(Flux.fromIterable(providers)
                .flatmap(provider -&gt; 
                    Mono.defer(() -&gt; provider.invokeHttpCall())
                .filterWhen(response -&gt; response.getMessage() == &quot;Success&quot;);
}

if you want to see result and println().
Just use .subsribe() method to excute it.

getResponse.subsribe(System.out::println);

答案2

得分: 0

Flux.fromIterable(providers)
    .concatMap(Provider::invokeHttpCall) // 确保按顺序调用providers
    .filter(response -> response.getMessage().equals("Success"))
    .next()
英文:
Flux.fromIterable(providers)
    .concatMap(Provider::invokeHttpCall) // ensures providers are called sequentially
    .filter(response -&gt; response.getMessage().equals(&quot;Success&quot;))
    .next()

huangapple
  • 本文由 发表于 2020年8月31日 17:18:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63668076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定