【问题标题】:Writing imperative code in Project Reactor在 Project Reactor 中编写命令式代码
【发布时间】:2021-11-14 22:53:53
【问题描述】:

我有一个类有以下两种方法。

public class Test1 {
    public Mono<String> blah1() {
        Mono<String> blah = Mono.just("blah1");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("blah1 done");
        return blah;
    }
    
    public Mono<String> blah2() {
        Mono<String> blah = Mono.just("blah2");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("blah2 done");
        return blah;
    }
}

我有以下 JUnit:

@Test
public void blah1Test() {
    Flux<Tuple2<String, String>> s = Flux.zip(test1.blah1(), test1.blah2());    
}

我的结果如下:

blah1 done
blah2 done

我希望 blah2 在 blah1 之前完成。因此我相信这是处理阻塞而不是非阻塞。我需要做什么才能将输出切换到 blah2 完成然后 blah1 完成?基本上为什么这些不并行处理?

提前感谢您的宝贵时间!

【问题讨论】:

    标签: spring spring-webflux project-reactor spring-mono


    【解决方案1】:

    sleepprintln 都在反应式管道之外执行。因此,blah1()blah2() 的行为都类似于常规的非反应性方法。

    试试这个:

    public Mono<String> blah1() {
        System.out.println("blah1 start");
        return Mono.just("blah1")
            .delayElement(Duration.ofMillis(5000))
            .doOnNext(e -> System.out.println("blah1 done"));
    }
    
    public Mono<String> blah2() {
        System.out.println("blah2 start");
        return Mono.just("blah2")
            .delayElement(Duration.ofMillis(1000))
            .doOnNext(e -> System.out.println("blah2 done"));
    }
    

    在这里,我们得到了预期的结果,因为打印发生在响应式管道中。

    输出:

    blah1  start 
    blah2 start 
    blah2 done
    blah1 done
    

    【讨论】:

    • 我正在尝试慢慢地将大型应用程序迁移到 spring 响应式随着时间的推移。有没有办法做到这一点,以便我可以处理在反应管道之外仍然使用单声道/通量的代码的方法?我有很多 CompletableFutures,但现在宁愿将它们更改为 Mono/flux,并在以后更改方法内部的代码。
    • 我可能已经回答了我自己的问题。看来我可以将代码放在 .doOnNext 中,它将在反应管道中处理。准确吗?
    • @Brian 当然doOnNext 可以,但并非适用于所有情况。更改应用程序状态或在那里执行异步操作不是一个好主意。
    • 我的大部分应用程序都是异步的,已经在使用 CompletableFutures,但并非适用于所有应用程序。感谢您的大力帮助!
    猜你喜欢
    • 2016-04-17
    • 2012-09-23
    • 2011-02-03
    • 2014-03-20
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    相关资源
    最近更新 更多