java - 从 Mono.first 发出第一个成功的结果
问题描述
我有两个Mono
s 要么返回 a404
要么产生 a result
。
我怎样才能将这两个Mono
s结合起来
result
一旦Mono
s 成功完成,就会发出 the 。Optional.empty
一旦所有Mono
s 产生 a404
或面临任何其他错误,就会返回an ?
我试过了
Mono<Result> mono0 = client.get()
.uri(uri1)
.retrieve()
.bodyToMono(Result.class)
.onErrorResume(e -> Mono.never());
Mono<Result> mono1 = client.get()
.uri(uri2)
.retrieve()
.bodyToMono(Result.class)
.onErrorResume(e -> Mono.never());
return Mono.first(mono0, mono1)
.blockOptional()
这种方法的问题是,如果两者都Mono
产生错误,它永远不会完成......
我想我需要像OnErrorDetach
......!?
为了使问题更清楚,我创建了一个 TestCase:
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
class DummyTest {
public Optional<String> getResult(Mono<String> m1, Mono<String> m2) {
return Mono.first(m1, m2)
// DoSomethingHere ?!??!?
.blockOptional();
}
@Test
void testFirstSuccessfullAndSecondErrorMono() {
Optional<String> result = getResult(Mono.just("Something"), Mono.error(new RuntimeException()));
assertThat(result, is(Optional.of("Something")));
}
@Test
void testSecondSuccessfullAndFirstErrorMono() {
Optional<String> result = getResult(Mono.error(new RuntimeException()), Mono.just("Something"));
assertThat(result, is(Optional.of("Something")));
}
@Test
void testTwoErrorMonosYieldEmpty() {
Optional<String> result =
getResult(Mono.error(new RuntimeException()), Mono.error(new RuntimeException()));
assertThat(result, is(Optional.empty()));
}
}
解决方案
问题Mono.first()
在于它需要第一个信号(不是第一个值),因此您最终会尝试Mono
永远延迟相应的信号以使其不重播完成信号。相反,您希望某些东西取第一个值。
而不是.onErrorResume(e -> Mono.never());
,使用.onErrorResume(e -> Mono.empty());
. 然后你可以使用:
Flux.merge(mono0, mono1).next();
(merge()
与相对concat()
)next()
应确保采用第一个值而忽略另一个值。blockOptional()
如果你愿意,你当然也可以。
推荐阅读
- java - Spring Log in system
- javascript - feathersjs/nodejs sequelize
- node.js - Error: filtered policies are not supported by this adapter
- jquery - Get each element values separately from URL in jquery
- jmeter - How to load test 10k requests per second using jmeter?
- build-system - icecc - icecream seems to have invoked itself recursively
- javascript - input type date doesn't seem to work in chrome
- c# - 如何以编程方式将撇号插入 Cell 对象(Visio 插件)
- sql-server - 有两个更新语句的 DEADLOCK 可能是什么原因?
- android - Kotlin Firebase 实时数据库事务错误