Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring反应式重用单值_Java_Spring_Spring Webflux_Project Reactor - Fatal编程技术网

Java Spring反应式重用单值

Java Spring反应式重用单值,java,spring,spring-webflux,project-reactor,Java,Spring,Spring Webflux,Project Reactor,我使用flatMap进行了一系列Mono转换。我设法将我的生产代码简化为这个测试用例: @Test public void test() { AtomicInteger iCounter = new AtomicInteger(1); Mono<String> iValueMono = Mono.fromSupplier(() -> { int iValue = iCounter.getAndIncrement(); System

我使用
flatMap
进行了一系列
Mono
转换。我设法将我的生产代码简化为这个测试用例:

@Test
public void test() {
    AtomicInteger iCounter = new AtomicInteger(1);
    Mono<String> iValueMono = Mono.fromSupplier(() -> {
        int iValue = iCounter.getAndIncrement();
        System.out.println("iValueMono CALL: " + iValue);
        return String.valueOf(iValue);
    });

    Mono<String> resultMono = Mono.just("X")
            .flatMap(append(iValueMono))
            .flatMap(append(iValueMono));

    StepVerifier.create(resultMono)
            .consumeNextWith(result -> assertThat(result).isEqualTo("X11"))
            .expectComplete()
            .verify();
}

private Function<String, Mono<String>> append(Mono<String> sMono) {
    return s -> sMono.map(v -> s + v);
}
我想——我现在知道这是不正确的——每次我在
append()
调用中映射
iValueMono
,供应商都会被重新执行以生成一个新值。我无法在生产代码中更改
iValueMono
的实现方式(例如,使其有状态地存储值)。我如何实现这一点,以便只调用一次值供应商,并得到最终结果“X11”


当然,我对一种非阻塞、反应式的方法很感兴趣。

我重新编写了您的测试,现在iValueMono似乎只执行一次:

@Test
public void test() {
    AtomicInteger iCounter = new AtomicInteger(0);
    Mono<String> iValueMono = getMono(iCounter.incrementAndGet());

    Mono<String> resultMono = Mono.just("X")
        .flatMap(append(iValueMono))
        .flatMap(append(iValueMono));

    StepVerifier.create(resultMono)
        .consumeNextWith(result -> assertEquals(result, "X11"))
        .expectComplete()
        .verify();
}

private Mono<String> getMono(int x) {
    System.out.println("Called");
    return Mono.just(String.valueOf(x));
}
@测试
公开无效测试(){
AtomicInteger iCounter=新的AtomicInteger(0);
Mono-iValueMono=getMono(iCounter.incrementAndGet());
Mono resultMono=Mono.just(“X”)
.flatMap(附加(iValueMono))
.flatMap(附加(iValueMono));
StepVerifier.create(resultMono)
.ConsumerNextWith(结果->资产质量(结果,“X11”))
.expectComplete()
.verify();
}
私有Mono getMono(int x){
System.out.println(“被调用”);
返回Mono.just(String.valueOf(x));
}
你觉得怎么样?它有用吗?

答案是:

将此单声道转换为热源,并缓存最后发出的信号,以供其他用户使用

使用它:

Mono<String> iValueMono = Mono.fromSupplier(() -> {
    int iValue = iCounter.getAndIncrement();
    System.out.println("iValueMono CALL: " + iValue);
    return String.valueOf(iValue);
}).cache();
Mono-iValueMono=Mono.fromSupplier(()->{
int iValue=iCounter.getAndIncrement();
System.out.println(“iValueMono调用:+iValue”);
返回字符串.valueOf(iValue);
}).cache();

只需给供应商打一次电话,即可获得所需的结果。

您必须使用Mono.fromSupplier吗?@vanillaSugar不需要,这是为了测试目的。在生产代码中,这来自使用WebClient的反应式HTTP调用-这就是为什么我希望避免多次调用它。因此,iValueMono结果是动态的,每次评估时都会发生变化-我只想评估一次(即使mono被映射多次),谢谢,但不是完全-我从服务调用中获得
iValueMono
,我无法修改它的实现方式。使用
Mono.just()
Mono<String> iValueMono = Mono.fromSupplier(() -> {
    int iValue = iCounter.getAndIncrement();
    System.out.println("iValueMono CALL: " + iValue);
    return String.valueOf(iValue);
}).cache();